diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 7e82efe..7bce4f3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -68,6 +68,7 @@
+
@@ -94,7 +95,6 @@
-
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 7e82efe..7bce4f3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -68,6 +68,7 @@
+
@@ -94,7 +95,6 @@
-
diff --git a/app/src/main/java/com/casic/br/operationsite/service/WebSocketMessageService.kt b/app/src/main/java/com/casic/br/operationsite/service/WebSocketMessageService.kt
deleted file mode 100644
index 52e08a8..0000000
--- a/app/src/main/java/com/casic/br/operationsite/service/WebSocketMessageService.kt
+++ /dev/null
@@ -1,92 +0,0 @@
-package com.casic.br.operationsite.service
-
-import android.app.Service
-import android.content.Intent
-import android.os.IBinder
-import android.util.Log
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.LifecycleOwner
-import androidx.lifecycle.LifecycleRegistry
-import androidx.lifecycle.lifecycleScope
-import com.casic.br.operationsite.utils.LocaleConstant
-import com.casic.br.operationsite.view.check.EnvironmentActivity
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-import okhttp3.OkHttpClient
-import okhttp3.Request
-import okhttp3.Response
-import okhttp3.WebSocket
-import okhttp3.WebSocketListener
-import java.util.concurrent.TimeUnit
-
-
-class WebSocketMessageService : Service(), LifecycleOwner {
-
- private val kTag = "WebSocketMessageService"
- private val registry = LifecycleRegistry(this)
-
- override fun getLifecycle(): Lifecycle {
- return registry
- }
-
- private var webSocket: WebSocket? = null
-
- override fun onCreate() {
- super.onCreate()
- Log.d(kTag, "onCreate: WebSocketMessageService")
- }
-
- override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
- //初始化WebSocket
- val httpClient = OkHttpClient.Builder()
- .connectTimeout(10, TimeUnit.SECONDS)
- .readTimeout(10, TimeUnit.SECONDS)
- .writeTimeout(10, TimeUnit.SECONDS)
- .build()
- lifecycleScope.launch(Dispatchers.IO) {
- val request = Request.Builder()
- .url("ws://192.168.10.142:8765")
- .build()
- httpClient.newWebSocket(request, object : WebSocketListener() {
- override fun onOpen(webSocket: WebSocket, response: Response) {
- super.onOpen(webSocket, response)
- this@WebSocketMessageService.webSocket = webSocket
- lifecycleScope.launch(Dispatchers.Main) {
- EnvironmentActivity.weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_CONNECTED_CODE)
- }
- }
-
- override fun onMessage(webSocket: WebSocket, text: String) {
- super.onMessage(webSocket, text)
-// text.writeToFile(createLogFile())
- Log.d(kTag, "onMessage: ${text.length}")
- lifecycleScope.launch(Dispatchers.Main) {
- val message = EnvironmentActivity.weakReferenceHandler.obtainMessage()
- message.what = LocaleConstant.WEBSOCKET_MESSAGE_CODE
- message.obj = text
- EnvironmentActivity.weakReferenceHandler.sendMessage(message)
- }
- }
-
- override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
- super.onFailure(webSocket, t, response)
- lifecycleScope.launch(Dispatchers.Main) {
- EnvironmentActivity.weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_DISCONNECTED_CODE)
- }
- }
- })
- httpClient.dispatcher.executorService.shutdown()
- }
- return START_STICKY
- }
-
- override fun onDestroy() {
- super.onDestroy()
- webSocket?.close(1000, null)
- Log.d(kTag, "onDestroy: WebSocketMessageService")
- }
-
- override fun onBind(intent: Intent?): IBinder? {
- return null
- }
-}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 7e82efe..7bce4f3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -68,6 +68,7 @@
+
@@ -94,7 +95,6 @@
-
diff --git a/app/src/main/java/com/casic/br/operationsite/service/WebSocketMessageService.kt b/app/src/main/java/com/casic/br/operationsite/service/WebSocketMessageService.kt
deleted file mode 100644
index 52e08a8..0000000
--- a/app/src/main/java/com/casic/br/operationsite/service/WebSocketMessageService.kt
+++ /dev/null
@@ -1,92 +0,0 @@
-package com.casic.br.operationsite.service
-
-import android.app.Service
-import android.content.Intent
-import android.os.IBinder
-import android.util.Log
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.LifecycleOwner
-import androidx.lifecycle.LifecycleRegistry
-import androidx.lifecycle.lifecycleScope
-import com.casic.br.operationsite.utils.LocaleConstant
-import com.casic.br.operationsite.view.check.EnvironmentActivity
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-import okhttp3.OkHttpClient
-import okhttp3.Request
-import okhttp3.Response
-import okhttp3.WebSocket
-import okhttp3.WebSocketListener
-import java.util.concurrent.TimeUnit
-
-
-class WebSocketMessageService : Service(), LifecycleOwner {
-
- private val kTag = "WebSocketMessageService"
- private val registry = LifecycleRegistry(this)
-
- override fun getLifecycle(): Lifecycle {
- return registry
- }
-
- private var webSocket: WebSocket? = null
-
- override fun onCreate() {
- super.onCreate()
- Log.d(kTag, "onCreate: WebSocketMessageService")
- }
-
- override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
- //初始化WebSocket
- val httpClient = OkHttpClient.Builder()
- .connectTimeout(10, TimeUnit.SECONDS)
- .readTimeout(10, TimeUnit.SECONDS)
- .writeTimeout(10, TimeUnit.SECONDS)
- .build()
- lifecycleScope.launch(Dispatchers.IO) {
- val request = Request.Builder()
- .url("ws://192.168.10.142:8765")
- .build()
- httpClient.newWebSocket(request, object : WebSocketListener() {
- override fun onOpen(webSocket: WebSocket, response: Response) {
- super.onOpen(webSocket, response)
- this@WebSocketMessageService.webSocket = webSocket
- lifecycleScope.launch(Dispatchers.Main) {
- EnvironmentActivity.weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_CONNECTED_CODE)
- }
- }
-
- override fun onMessage(webSocket: WebSocket, text: String) {
- super.onMessage(webSocket, text)
-// text.writeToFile(createLogFile())
- Log.d(kTag, "onMessage: ${text.length}")
- lifecycleScope.launch(Dispatchers.Main) {
- val message = EnvironmentActivity.weakReferenceHandler.obtainMessage()
- message.what = LocaleConstant.WEBSOCKET_MESSAGE_CODE
- message.obj = text
- EnvironmentActivity.weakReferenceHandler.sendMessage(message)
- }
- }
-
- override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
- super.onFailure(webSocket, t, response)
- lifecycleScope.launch(Dispatchers.Main) {
- EnvironmentActivity.weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_DISCONNECTED_CODE)
- }
- }
- })
- httpClient.dispatcher.executorService.shutdown()
- }
- return START_STICKY
- }
-
- override fun onDestroy() {
- super.onDestroy()
- webSocket?.close(1000, null)
- Log.d(kTag, "onDestroy: WebSocketMessageService")
- }
-
- override fun onBind(intent: Intent?): IBinder? {
- return null
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt
index 3676eab..725b743 100644
--- a/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt
+++ b/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt
@@ -27,7 +27,6 @@
import com.casic.br.operationsite.utils.DeviceType
import com.casic.br.operationsite.utils.RuntimeCache
import com.casic.br.operationsite.view.check.DisclosureActivity
-import com.casic.br.operationsite.vm.AlarmViewModel
import com.casic.br.operationsite.vm.DeviceViewModel
import com.casic.br.operationsite.vm.LoginViewModel
import com.casic.br.operationsite.vm.WorkSiteViewModel
@@ -50,7 +49,6 @@
private lateinit var workSiteViewModel: WorkSiteViewModel
private lateinit var deviceViewModel: DeviceViewModel
private lateinit var loginViewModel: LoginViewModel
- private lateinit var alarmViewModel: AlarmViewModel
private lateinit var userHelmetCode: String
private val polygonOptions by lazy { PolygonOptions() }
private val latLngArray: MutableList = ArrayList()
@@ -254,11 +252,6 @@
navigatePageTo()
}
}
-
- alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java]
- alarmViewModel.alarmState.observe(this) {
-
- }
}
override fun onMarkerClick(marker: Marker?): Boolean {
@@ -394,15 +387,6 @@
navigatePageTo()
}
- binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked ->
- val state = if (isChecked) {
- "1"
- } else {
- "0"
- }
- alarmViewModel.changeAlarmState("", state)
- }
-
binding.reloadDataView.setOnClickListener {
aMap.clear()
@@ -416,7 +400,6 @@
override fun onResume() {
super.onResume()
binding.mapView.onResume()
- alarmViewModel.getAlarmDetail(this, "")
}
override fun onPause() {
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 7e82efe..7bce4f3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -68,6 +68,7 @@
+
@@ -94,7 +95,6 @@
-
diff --git a/app/src/main/java/com/casic/br/operationsite/service/WebSocketMessageService.kt b/app/src/main/java/com/casic/br/operationsite/service/WebSocketMessageService.kt
deleted file mode 100644
index 52e08a8..0000000
--- a/app/src/main/java/com/casic/br/operationsite/service/WebSocketMessageService.kt
+++ /dev/null
@@ -1,92 +0,0 @@
-package com.casic.br.operationsite.service
-
-import android.app.Service
-import android.content.Intent
-import android.os.IBinder
-import android.util.Log
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.LifecycleOwner
-import androidx.lifecycle.LifecycleRegistry
-import androidx.lifecycle.lifecycleScope
-import com.casic.br.operationsite.utils.LocaleConstant
-import com.casic.br.operationsite.view.check.EnvironmentActivity
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-import okhttp3.OkHttpClient
-import okhttp3.Request
-import okhttp3.Response
-import okhttp3.WebSocket
-import okhttp3.WebSocketListener
-import java.util.concurrent.TimeUnit
-
-
-class WebSocketMessageService : Service(), LifecycleOwner {
-
- private val kTag = "WebSocketMessageService"
- private val registry = LifecycleRegistry(this)
-
- override fun getLifecycle(): Lifecycle {
- return registry
- }
-
- private var webSocket: WebSocket? = null
-
- override fun onCreate() {
- super.onCreate()
- Log.d(kTag, "onCreate: WebSocketMessageService")
- }
-
- override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
- //初始化WebSocket
- val httpClient = OkHttpClient.Builder()
- .connectTimeout(10, TimeUnit.SECONDS)
- .readTimeout(10, TimeUnit.SECONDS)
- .writeTimeout(10, TimeUnit.SECONDS)
- .build()
- lifecycleScope.launch(Dispatchers.IO) {
- val request = Request.Builder()
- .url("ws://192.168.10.142:8765")
- .build()
- httpClient.newWebSocket(request, object : WebSocketListener() {
- override fun onOpen(webSocket: WebSocket, response: Response) {
- super.onOpen(webSocket, response)
- this@WebSocketMessageService.webSocket = webSocket
- lifecycleScope.launch(Dispatchers.Main) {
- EnvironmentActivity.weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_CONNECTED_CODE)
- }
- }
-
- override fun onMessage(webSocket: WebSocket, text: String) {
- super.onMessage(webSocket, text)
-// text.writeToFile(createLogFile())
- Log.d(kTag, "onMessage: ${text.length}")
- lifecycleScope.launch(Dispatchers.Main) {
- val message = EnvironmentActivity.weakReferenceHandler.obtainMessage()
- message.what = LocaleConstant.WEBSOCKET_MESSAGE_CODE
- message.obj = text
- EnvironmentActivity.weakReferenceHandler.sendMessage(message)
- }
- }
-
- override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
- super.onFailure(webSocket, t, response)
- lifecycleScope.launch(Dispatchers.Main) {
- EnvironmentActivity.weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_DISCONNECTED_CODE)
- }
- }
- })
- httpClient.dispatcher.executorService.shutdown()
- }
- return START_STICKY
- }
-
- override fun onDestroy() {
- super.onDestroy()
- webSocket?.close(1000, null)
- Log.d(kTag, "onDestroy: WebSocketMessageService")
- }
-
- override fun onBind(intent: Intent?): IBinder? {
- return null
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt
index 3676eab..725b743 100644
--- a/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt
+++ b/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt
@@ -27,7 +27,6 @@
import com.casic.br.operationsite.utils.DeviceType
import com.casic.br.operationsite.utils.RuntimeCache
import com.casic.br.operationsite.view.check.DisclosureActivity
-import com.casic.br.operationsite.vm.AlarmViewModel
import com.casic.br.operationsite.vm.DeviceViewModel
import com.casic.br.operationsite.vm.LoginViewModel
import com.casic.br.operationsite.vm.WorkSiteViewModel
@@ -50,7 +49,6 @@
private lateinit var workSiteViewModel: WorkSiteViewModel
private lateinit var deviceViewModel: DeviceViewModel
private lateinit var loginViewModel: LoginViewModel
- private lateinit var alarmViewModel: AlarmViewModel
private lateinit var userHelmetCode: String
private val polygonOptions by lazy { PolygonOptions() }
private val latLngArray: MutableList = ArrayList()
@@ -254,11 +252,6 @@
navigatePageTo()
}
}
-
- alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java]
- alarmViewModel.alarmState.observe(this) {
-
- }
}
override fun onMarkerClick(marker: Marker?): Boolean {
@@ -394,15 +387,6 @@
navigatePageTo()
}
- binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked ->
- val state = if (isChecked) {
- "1"
- } else {
- "0"
- }
- alarmViewModel.changeAlarmState("", state)
- }
-
binding.reloadDataView.setOnClickListener {
aMap.clear()
@@ -416,7 +400,6 @@
override fun onResume() {
super.onResume()
binding.mapView.onResume()
- alarmViewModel.getAlarmDetail(this, "")
}
override fun onPause() {
diff --git a/app/src/main/java/com/casic/br/operationsite/view/check/EnvironmentActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/check/EnvironmentActivity.kt
index cec8a1f..50bb949 100644
--- a/app/src/main/java/com/casic/br/operationsite/view/check/EnvironmentActivity.kt
+++ b/app/src/main/java/com/casic/br/operationsite/view/check/EnvironmentActivity.kt
@@ -1,6 +1,5 @@
package com.casic.br.operationsite.view.check
-import android.content.Intent
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Bundle
@@ -9,10 +8,10 @@
import android.util.Base64
import android.util.Log
import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.lifecycleScope
import com.casic.br.operationsite.R
import com.casic.br.operationsite.databinding.ActivityEnvironmentBinding
import com.casic.br.operationsite.extensions.initImmersionBar
-import com.casic.br.operationsite.service.WebSocketMessageService
import com.casic.br.operationsite.utils.LocaleConstant
import com.casic.br.operationsite.utils.RuntimeCache
import com.casic.br.operationsite.utils.tcp.ISocketListener
@@ -28,25 +27,30 @@
import com.pengxh.kt.lite.utils.ActivityStackManager
import com.pengxh.kt.lite.utils.WeakReferenceHandler
import com.pengxh.kt.lite.widget.TitleBarView
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import okhttp3.Response
+import okhttp3.WebSocket
+import okhttp3.WebSocketListener
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.util.Timer
import java.util.TimerTask
+import java.util.concurrent.TimeUnit
class EnvironmentActivity : KotlinBaseActivity(), Handler.Callback {
- companion object {
- lateinit var weakReferenceHandler: WeakReferenceHandler
- }
-
private val kTag = "EnvironmentActivity"
private val context = this
private val timeFormat by lazy { SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA) }
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
private lateinit var constructionCheckViewModel: ConstructionCheckViewModel
private lateinit var workSiteViewModel: WorkSiteViewModel
private lateinit var timer: Timer
- private var isStart = false
+ private lateinit var webSocket: WebSocket
private var isFirstConfirm = false
private var isSecondConfirm = false
private var isThirdConfirm = false
@@ -54,7 +58,7 @@
override fun handleMessage(msg: Message): Boolean {
when (msg.what) {
- LocaleConstant.WEBSOCKET_CONNECTED_CODE -> "WebSocket连接成功".show(this)
+ LocaleConstant.WEBSOCKET_CONNECTED_CODE -> "AI连接成功".show(this)
LocaleConstant.WEBSOCKET_MESSAGE_CODE -> {
try {
@@ -68,7 +72,7 @@
}
}
- LocaleConstant.WEBSOCKET_DISCONNECTED_CODE -> "WebSocket连接失败".show(this)
+ LocaleConstant.WEBSOCKET_DISCONNECTED_CODE -> "AI连接失败".show(this)
}
return true
}
@@ -80,7 +84,6 @@
return@setOnClickListener
}
SocketManager.get.send(LocaleConstant.START_ENV_COMMAND)
- isStart = true
constructionCheckViewModel.setCurrentPhase(this, "before_operation_environment")
//播放RTSP流
binding.videoView.setVideoURI(Uri.parse("rtsp://192.168.10.137:554"))
@@ -131,13 +134,20 @@
}
isThirdConfirm = true
}
+
+ binding.endEnvCheckButton.setOnClickListener {
+ if (SocketManager.get.statusCode != ISocketListener.STATUS_CONNECT_SUCCESS) {
+ "指令发送失败,请确认是否处于同一网段".show(this)
+ return@setOnClickListener
+ }
+ SocketManager.get.send(LocaleConstant.END_ENV_COMMAND)
+ navigatePageTo()
+ }
}
override fun initOnCreate(savedInstanceState: Bundle?) {
ActivityStackManager.addActivity(this)
- startService(Intent(this, WebSocketMessageService::class.java))
-
weakReferenceHandler = WeakReferenceHandler(this)
constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java]
@@ -146,6 +156,8 @@
binding.videoView.start()
}
+ startWebSocket()
+
timer = Timer()
workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java]
timer.schedule(object : TimerTask() {
@@ -178,6 +190,45 @@
}
}
+ private fun startWebSocket() {
+ //初始化WebSocket
+ val httpClient = OkHttpClient.Builder()
+ .connectTimeout(10, TimeUnit.SECONDS)
+ .readTimeout(10, TimeUnit.SECONDS)
+ .writeTimeout(10, TimeUnit.SECONDS)
+ .build()
+ lifecycleScope.launch(Dispatchers.IO) {
+ val request = Request.Builder().url("ws://192.168.10.142:8765").build()
+ httpClient.newWebSocket(request, object : WebSocketListener() {
+ override fun onOpen(webSocket: WebSocket, response: Response) {
+ super.onOpen(webSocket, response)
+ this@EnvironmentActivity.webSocket = webSocket
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_CONNECTED_CODE)
+ }
+ }
+
+ override fun onMessage(webSocket: WebSocket, text: String) {
+ super.onMessage(webSocket, text)
+ lifecycleScope.launch(Dispatchers.Main) {
+ val message = weakReferenceHandler.obtainMessage()
+ message.what = LocaleConstant.WEBSOCKET_MESSAGE_CODE
+ message.obj = text
+ weakReferenceHandler.sendMessage(message)
+ }
+ }
+
+ override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
+ super.onFailure(webSocket, t, response)
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_DISCONNECTED_CODE)
+ }
+ }
+ })
+ httpClient.dispatcher.executorService.shutdown()
+ }
+ }
+
override fun initViewBinding(): ActivityEnvironmentBinding {
return ActivityEnvironmentBinding.inflate(layoutInflater)
}
@@ -203,5 +254,6 @@
super.onDestroy()
binding.videoView.suspend()
timer.cancel()
+ webSocket.close(1000, null)
}
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 7e82efe..7bce4f3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -68,6 +68,7 @@
+
@@ -94,7 +95,6 @@
-
diff --git a/app/src/main/java/com/casic/br/operationsite/service/WebSocketMessageService.kt b/app/src/main/java/com/casic/br/operationsite/service/WebSocketMessageService.kt
deleted file mode 100644
index 52e08a8..0000000
--- a/app/src/main/java/com/casic/br/operationsite/service/WebSocketMessageService.kt
+++ /dev/null
@@ -1,92 +0,0 @@
-package com.casic.br.operationsite.service
-
-import android.app.Service
-import android.content.Intent
-import android.os.IBinder
-import android.util.Log
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.LifecycleOwner
-import androidx.lifecycle.LifecycleRegistry
-import androidx.lifecycle.lifecycleScope
-import com.casic.br.operationsite.utils.LocaleConstant
-import com.casic.br.operationsite.view.check.EnvironmentActivity
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-import okhttp3.OkHttpClient
-import okhttp3.Request
-import okhttp3.Response
-import okhttp3.WebSocket
-import okhttp3.WebSocketListener
-import java.util.concurrent.TimeUnit
-
-
-class WebSocketMessageService : Service(), LifecycleOwner {
-
- private val kTag = "WebSocketMessageService"
- private val registry = LifecycleRegistry(this)
-
- override fun getLifecycle(): Lifecycle {
- return registry
- }
-
- private var webSocket: WebSocket? = null
-
- override fun onCreate() {
- super.onCreate()
- Log.d(kTag, "onCreate: WebSocketMessageService")
- }
-
- override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
- //初始化WebSocket
- val httpClient = OkHttpClient.Builder()
- .connectTimeout(10, TimeUnit.SECONDS)
- .readTimeout(10, TimeUnit.SECONDS)
- .writeTimeout(10, TimeUnit.SECONDS)
- .build()
- lifecycleScope.launch(Dispatchers.IO) {
- val request = Request.Builder()
- .url("ws://192.168.10.142:8765")
- .build()
- httpClient.newWebSocket(request, object : WebSocketListener() {
- override fun onOpen(webSocket: WebSocket, response: Response) {
- super.onOpen(webSocket, response)
- this@WebSocketMessageService.webSocket = webSocket
- lifecycleScope.launch(Dispatchers.Main) {
- EnvironmentActivity.weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_CONNECTED_CODE)
- }
- }
-
- override fun onMessage(webSocket: WebSocket, text: String) {
- super.onMessage(webSocket, text)
-// text.writeToFile(createLogFile())
- Log.d(kTag, "onMessage: ${text.length}")
- lifecycleScope.launch(Dispatchers.Main) {
- val message = EnvironmentActivity.weakReferenceHandler.obtainMessage()
- message.what = LocaleConstant.WEBSOCKET_MESSAGE_CODE
- message.obj = text
- EnvironmentActivity.weakReferenceHandler.sendMessage(message)
- }
- }
-
- override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
- super.onFailure(webSocket, t, response)
- lifecycleScope.launch(Dispatchers.Main) {
- EnvironmentActivity.weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_DISCONNECTED_CODE)
- }
- }
- })
- httpClient.dispatcher.executorService.shutdown()
- }
- return START_STICKY
- }
-
- override fun onDestroy() {
- super.onDestroy()
- webSocket?.close(1000, null)
- Log.d(kTag, "onDestroy: WebSocketMessageService")
- }
-
- override fun onBind(intent: Intent?): IBinder? {
- return null
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt
index 3676eab..725b743 100644
--- a/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt
+++ b/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt
@@ -27,7 +27,6 @@
import com.casic.br.operationsite.utils.DeviceType
import com.casic.br.operationsite.utils.RuntimeCache
import com.casic.br.operationsite.view.check.DisclosureActivity
-import com.casic.br.operationsite.vm.AlarmViewModel
import com.casic.br.operationsite.vm.DeviceViewModel
import com.casic.br.operationsite.vm.LoginViewModel
import com.casic.br.operationsite.vm.WorkSiteViewModel
@@ -50,7 +49,6 @@
private lateinit var workSiteViewModel: WorkSiteViewModel
private lateinit var deviceViewModel: DeviceViewModel
private lateinit var loginViewModel: LoginViewModel
- private lateinit var alarmViewModel: AlarmViewModel
private lateinit var userHelmetCode: String
private val polygonOptions by lazy { PolygonOptions() }
private val latLngArray: MutableList = ArrayList()
@@ -254,11 +252,6 @@
navigatePageTo()
}
}
-
- alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java]
- alarmViewModel.alarmState.observe(this) {
-
- }
}
override fun onMarkerClick(marker: Marker?): Boolean {
@@ -394,15 +387,6 @@
navigatePageTo()
}
- binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked ->
- val state = if (isChecked) {
- "1"
- } else {
- "0"
- }
- alarmViewModel.changeAlarmState("", state)
- }
-
binding.reloadDataView.setOnClickListener {
aMap.clear()
@@ -416,7 +400,6 @@
override fun onResume() {
super.onResume()
binding.mapView.onResume()
- alarmViewModel.getAlarmDetail(this, "")
}
override fun onPause() {
diff --git a/app/src/main/java/com/casic/br/operationsite/view/check/EnvironmentActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/check/EnvironmentActivity.kt
index cec8a1f..50bb949 100644
--- a/app/src/main/java/com/casic/br/operationsite/view/check/EnvironmentActivity.kt
+++ b/app/src/main/java/com/casic/br/operationsite/view/check/EnvironmentActivity.kt
@@ -1,6 +1,5 @@
package com.casic.br.operationsite.view.check
-import android.content.Intent
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Bundle
@@ -9,10 +8,10 @@
import android.util.Base64
import android.util.Log
import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.lifecycleScope
import com.casic.br.operationsite.R
import com.casic.br.operationsite.databinding.ActivityEnvironmentBinding
import com.casic.br.operationsite.extensions.initImmersionBar
-import com.casic.br.operationsite.service.WebSocketMessageService
import com.casic.br.operationsite.utils.LocaleConstant
import com.casic.br.operationsite.utils.RuntimeCache
import com.casic.br.operationsite.utils.tcp.ISocketListener
@@ -28,25 +27,30 @@
import com.pengxh.kt.lite.utils.ActivityStackManager
import com.pengxh.kt.lite.utils.WeakReferenceHandler
import com.pengxh.kt.lite.widget.TitleBarView
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import okhttp3.Response
+import okhttp3.WebSocket
+import okhttp3.WebSocketListener
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.util.Timer
import java.util.TimerTask
+import java.util.concurrent.TimeUnit
class EnvironmentActivity : KotlinBaseActivity(), Handler.Callback {
- companion object {
- lateinit var weakReferenceHandler: WeakReferenceHandler
- }
-
private val kTag = "EnvironmentActivity"
private val context = this
private val timeFormat by lazy { SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA) }
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
private lateinit var constructionCheckViewModel: ConstructionCheckViewModel
private lateinit var workSiteViewModel: WorkSiteViewModel
private lateinit var timer: Timer
- private var isStart = false
+ private lateinit var webSocket: WebSocket
private var isFirstConfirm = false
private var isSecondConfirm = false
private var isThirdConfirm = false
@@ -54,7 +58,7 @@
override fun handleMessage(msg: Message): Boolean {
when (msg.what) {
- LocaleConstant.WEBSOCKET_CONNECTED_CODE -> "WebSocket连接成功".show(this)
+ LocaleConstant.WEBSOCKET_CONNECTED_CODE -> "AI连接成功".show(this)
LocaleConstant.WEBSOCKET_MESSAGE_CODE -> {
try {
@@ -68,7 +72,7 @@
}
}
- LocaleConstant.WEBSOCKET_DISCONNECTED_CODE -> "WebSocket连接失败".show(this)
+ LocaleConstant.WEBSOCKET_DISCONNECTED_CODE -> "AI连接失败".show(this)
}
return true
}
@@ -80,7 +84,6 @@
return@setOnClickListener
}
SocketManager.get.send(LocaleConstant.START_ENV_COMMAND)
- isStart = true
constructionCheckViewModel.setCurrentPhase(this, "before_operation_environment")
//播放RTSP流
binding.videoView.setVideoURI(Uri.parse("rtsp://192.168.10.137:554"))
@@ -131,13 +134,20 @@
}
isThirdConfirm = true
}
+
+ binding.endEnvCheckButton.setOnClickListener {
+ if (SocketManager.get.statusCode != ISocketListener.STATUS_CONNECT_SUCCESS) {
+ "指令发送失败,请确认是否处于同一网段".show(this)
+ return@setOnClickListener
+ }
+ SocketManager.get.send(LocaleConstant.END_ENV_COMMAND)
+ navigatePageTo()
+ }
}
override fun initOnCreate(savedInstanceState: Bundle?) {
ActivityStackManager.addActivity(this)
- startService(Intent(this, WebSocketMessageService::class.java))
-
weakReferenceHandler = WeakReferenceHandler(this)
constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java]
@@ -146,6 +156,8 @@
binding.videoView.start()
}
+ startWebSocket()
+
timer = Timer()
workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java]
timer.schedule(object : TimerTask() {
@@ -178,6 +190,45 @@
}
}
+ private fun startWebSocket() {
+ //初始化WebSocket
+ val httpClient = OkHttpClient.Builder()
+ .connectTimeout(10, TimeUnit.SECONDS)
+ .readTimeout(10, TimeUnit.SECONDS)
+ .writeTimeout(10, TimeUnit.SECONDS)
+ .build()
+ lifecycleScope.launch(Dispatchers.IO) {
+ val request = Request.Builder().url("ws://192.168.10.142:8765").build()
+ httpClient.newWebSocket(request, object : WebSocketListener() {
+ override fun onOpen(webSocket: WebSocket, response: Response) {
+ super.onOpen(webSocket, response)
+ this@EnvironmentActivity.webSocket = webSocket
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_CONNECTED_CODE)
+ }
+ }
+
+ override fun onMessage(webSocket: WebSocket, text: String) {
+ super.onMessage(webSocket, text)
+ lifecycleScope.launch(Dispatchers.Main) {
+ val message = weakReferenceHandler.obtainMessage()
+ message.what = LocaleConstant.WEBSOCKET_MESSAGE_CODE
+ message.obj = text
+ weakReferenceHandler.sendMessage(message)
+ }
+ }
+
+ override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
+ super.onFailure(webSocket, t, response)
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_DISCONNECTED_CODE)
+ }
+ }
+ })
+ httpClient.dispatcher.executorService.shutdown()
+ }
+ }
+
override fun initViewBinding(): ActivityEnvironmentBinding {
return ActivityEnvironmentBinding.inflate(layoutInflater)
}
@@ -203,5 +254,6 @@
super.onDestroy()
binding.videoView.suspend()
timer.cancel()
+ webSocket.close(1000, null)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/operationsite/view/check/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/check/GuardiansActivity.kt
new file mode 100644
index 0000000..8805701
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/check/GuardiansActivity.kt
@@ -0,0 +1,270 @@
+package com.casic.br.operationsite.view.check
+
+import android.graphics.BitmapFactory
+import android.net.Uri
+import android.os.Bundle
+import android.os.Handler
+import android.os.Message
+import android.util.Base64
+import android.util.Log
+import android.view.View
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.lifecycleScope
+import com.casic.br.operationsite.R
+import com.casic.br.operationsite.databinding.ActivityGuardiansBinding
+import com.casic.br.operationsite.extensions.initImmersionBar
+import com.casic.br.operationsite.utils.LocaleConstant
+import com.casic.br.operationsite.utils.RuntimeCache
+import com.casic.br.operationsite.view.BigImageActivity
+import com.casic.br.operationsite.view.MainActivity
+import com.casic.br.operationsite.vm.AlarmViewModel
+import com.casic.br.operationsite.vm.ConstructionCheckViewModel
+import com.casic.br.operationsite.vm.WorkSiteViewModel
+import com.pengxh.kt.lite.adapter.EditableImageAdapter
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets
+import com.pengxh.kt.lite.extensions.createImageFileDir
+import com.pengxh.kt.lite.extensions.dp2px
+import com.pengxh.kt.lite.extensions.getScreenWidth
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.saveImage
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.extensions.toJson
+import com.pengxh.kt.lite.utils.ActivityStackManager
+import com.pengxh.kt.lite.utils.WeakReferenceHandler
+import com.pengxh.kt.lite.widget.TitleBarView
+import com.pengxh.kt.lite.widget.dialog.AlertControlDialog
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import okhttp3.Response
+import okhttp3.WebSocket
+import okhttp3.WebSocketListener
+import java.text.SimpleDateFormat
+import java.util.Date
+import java.util.Locale
+import java.util.Timer
+import java.util.TimerTask
+import java.util.concurrent.TimeUnit
+
+class GuardiansActivity : KotlinBaseActivity(), Handler.Callback {
+
+ private val kTag = "GuardiansActivity"
+ private val context = this
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
+ private lateinit var alarmViewModel: AlarmViewModel
+ private lateinit var constructionCheckViewModel: ConstructionCheckViewModel
+ private lateinit var workSiteViewModel: WorkSiteViewModel
+ private lateinit var imageAdapter: EditableImageAdapter
+ private lateinit var webSocket: WebSocket
+ private lateinit var timer: Timer
+ private val timeFormat by lazy { SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA) }
+ private val marginOffset by lazy { 1.dp2px(this) }
+ private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径
+
+ override fun initEvent() {
+ binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked ->
+ val state = if (isChecked) {
+ "1"
+ } else {
+ "0"
+ }
+ alarmViewModel.changeAlarmState("", state)
+ }
+
+ binding.setVideoRegionButton.setOnClickListener {
+ val region = binding.regionView.getConfirmedPoints()
+ Log.d(kTag, region.toJson())
+
+ constructionCheckViewModel.setVideoRegion(this, region)
+ }
+
+ binding.startVideoCheckButton.setOnClickListener {
+ constructionCheckViewModel.setCurrentPhase(this, "in_operation")
+ }
+
+ imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener {
+ override fun onAddImageClick() {
+ "当前模式不支持手动添加图片".show(context)
+ }
+
+ override fun onItemClick(position: Int) {
+ if (recyclerViewImages[position].isEmpty()) {
+ "图片加载失败,无法查看大图".show(context)
+ } else {
+ navigatePageTo(position, recyclerViewImages)
+ }
+ }
+
+ override fun onItemLongClick(view: View?, position: Int) {
+ recyclerViewImages.removeAt(position)
+ imageAdapter.notifyDataSetChanged()
+ }
+ })
+
+ binding.endTaskButton.setOnClickListener {
+ AlertControlDialog.Builder().setContext(this).setTitle("温馨提示")
+ .setMessage("确定结束此次施工?").setNegativeButton("取消").setPositiveButton("确定")
+ .setOnDialogButtonClickListener(object :
+ AlertControlDialog.OnDialogButtonClickListener {
+ override fun onConfirmClick() {
+ ActivityStackManager.finishActivity(DisclosureActivity::class.java)
+ ActivityStackManager.finishActivity(EnvironmentActivity::class.java)
+ ActivityStackManager.finishActivity(SuppliesActivity::class.java)
+ navigatePageTo()
+ finish()
+ }
+
+ override fun onCancelClick() {}
+ }).build().show()
+ }
+ }
+
+ override fun initOnCreate(savedInstanceState: Bundle?) {
+ ActivityStackManager.addActivity(this)
+
+ weakReferenceHandler = WeakReferenceHandler(this)
+ //播放RTSP流
+ binding.videoView.setVideoURI(Uri.parse("rtsp://192.168.10.137:554"))
+ binding.videoView.setOnPreparedListener {
+ binding.videoView.requestFocus()
+ binding.videoView.start()
+ }
+ startWebSocket()
+
+ alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java]
+ alarmViewModel.alarmState.observe(this) {
+
+ }
+
+ constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java]
+ constructionCheckViewModel.postResult.observe(this) {
+ if (it.code == 200) {
+ "区域配置成功".show(this)
+ }
+ }
+
+ //左右边距
+ val viewWidth = getScreenWidth() - (15 + 15).dp2px(this)
+ imageAdapter = EditableImageAdapter(this, recyclerViewImages, viewWidth, 3, 3)
+ binding.recyclerView.addItemDecoration(
+ RecyclerViewItemOffsets(marginOffset, marginOffset, marginOffset, marginOffset)
+ )
+ binding.recyclerView.adapter = imageAdapter
+
+ timer = Timer()
+ workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java]
+ timer.schedule(object : TimerTask() {
+ override fun run() {
+ workSiteViewModel.getWorkers(context, RuntimeCache.projectId)
+ }
+ }, 0, 5000)
+ workSiteViewModel.workerResult.observe(this) {
+ if (it.code == 200) {
+ it.data.forEach { worker ->
+ if (worker.lat.isNotBlank() && worker.lng.isNotBlank()) {
+ val value =
+ "CO:${worker.co}ppm, CH4:${worker.gas}ppm, H2S:${worker.co}ppm, O2:${worker.o2}%VOL"
+ Log.d(kTag, "value: $value")
+ }
+ }
+ }
+ }
+ }
+
+ override fun handleMessage(msg: Message): Boolean {
+ when (msg.what) {
+ LocaleConstant.WEBSOCKET_CONNECTED_CODE -> "AI连接成功".show(this)
+
+ LocaleConstant.WEBSOCKET_MESSAGE_CODE -> {
+ try {
+ val bitmapArray = Base64.decode((msg.obj as String), Base64.DEFAULT)
+ val bitmap = BitmapFactory.decodeByteArray(bitmapArray, 0, bitmapArray.size)
+ val imagePath = "/${createImageFileDir()}/IMG${timeFormat.format(Date())}.png"
+ Log.d(kTag, "imagePath: $imagePath")
+ bitmap.saveImage(imagePath)
+ if (recyclerViewImages.size == 3) {
+ recyclerViewImages.removeAt(0)
+ }
+ recyclerViewImages.add(imagePath)
+ imageAdapter.notifyDataSetChanged()
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ LocaleConstant.WEBSOCKET_DISCONNECTED_CODE -> "AI连接失败".show(this)
+ }
+ return true
+ }
+
+ private fun startWebSocket() {
+ //初始化WebSocket
+ val httpClient = OkHttpClient.Builder().connectTimeout(10, TimeUnit.SECONDS)
+ .readTimeout(10, TimeUnit.SECONDS).writeTimeout(10, TimeUnit.SECONDS).build()
+ lifecycleScope.launch(Dispatchers.IO) {
+ val request = Request.Builder().url("ws://192.168.10.142:8765").build()
+ httpClient.newWebSocket(request, object : WebSocketListener() {
+ override fun onOpen(webSocket: WebSocket, response: Response) {
+ super.onOpen(webSocket, response)
+ this@GuardiansActivity.webSocket = webSocket
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_CONNECTED_CODE)
+ }
+ }
+
+ override fun onMessage(webSocket: WebSocket, text: String) {
+ super.onMessage(webSocket, text)
+ lifecycleScope.launch(Dispatchers.Main) {
+ val message = weakReferenceHandler.obtainMessage()
+ message.what = LocaleConstant.WEBSOCKET_MESSAGE_CODE
+ message.obj = text
+ weakReferenceHandler.sendMessage(message)
+ }
+ }
+
+ override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
+ super.onFailure(webSocket, t, response)
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_DISCONNECTED_CODE)
+ }
+ }
+ })
+ httpClient.dispatcher.executorService.shutdown()
+ }
+ }
+
+ override fun initViewBinding(): ActivityGuardiansBinding {
+ return ActivityGuardiansBinding.inflate(layoutInflater)
+ }
+
+ override fun observeRequestState() {
+
+ }
+
+ override fun setupTopBarLayout() {
+ binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor)
+ binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener {
+ override fun onLeftClick() {
+ finish()
+ }
+
+ override fun onRightClick() {
+
+ }
+ })
+ }
+
+ override fun onResume() {
+ super.onResume()
+ alarmViewModel.getAlarmState(this)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ binding.videoView.suspend()
+ timer.cancel()
+ webSocket.close(1000, null)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 7e82efe..7bce4f3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -68,6 +68,7 @@
+
@@ -94,7 +95,6 @@
-
diff --git a/app/src/main/java/com/casic/br/operationsite/service/WebSocketMessageService.kt b/app/src/main/java/com/casic/br/operationsite/service/WebSocketMessageService.kt
deleted file mode 100644
index 52e08a8..0000000
--- a/app/src/main/java/com/casic/br/operationsite/service/WebSocketMessageService.kt
+++ /dev/null
@@ -1,92 +0,0 @@
-package com.casic.br.operationsite.service
-
-import android.app.Service
-import android.content.Intent
-import android.os.IBinder
-import android.util.Log
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.LifecycleOwner
-import androidx.lifecycle.LifecycleRegistry
-import androidx.lifecycle.lifecycleScope
-import com.casic.br.operationsite.utils.LocaleConstant
-import com.casic.br.operationsite.view.check.EnvironmentActivity
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-import okhttp3.OkHttpClient
-import okhttp3.Request
-import okhttp3.Response
-import okhttp3.WebSocket
-import okhttp3.WebSocketListener
-import java.util.concurrent.TimeUnit
-
-
-class WebSocketMessageService : Service(), LifecycleOwner {
-
- private val kTag = "WebSocketMessageService"
- private val registry = LifecycleRegistry(this)
-
- override fun getLifecycle(): Lifecycle {
- return registry
- }
-
- private var webSocket: WebSocket? = null
-
- override fun onCreate() {
- super.onCreate()
- Log.d(kTag, "onCreate: WebSocketMessageService")
- }
-
- override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
- //初始化WebSocket
- val httpClient = OkHttpClient.Builder()
- .connectTimeout(10, TimeUnit.SECONDS)
- .readTimeout(10, TimeUnit.SECONDS)
- .writeTimeout(10, TimeUnit.SECONDS)
- .build()
- lifecycleScope.launch(Dispatchers.IO) {
- val request = Request.Builder()
- .url("ws://192.168.10.142:8765")
- .build()
- httpClient.newWebSocket(request, object : WebSocketListener() {
- override fun onOpen(webSocket: WebSocket, response: Response) {
- super.onOpen(webSocket, response)
- this@WebSocketMessageService.webSocket = webSocket
- lifecycleScope.launch(Dispatchers.Main) {
- EnvironmentActivity.weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_CONNECTED_CODE)
- }
- }
-
- override fun onMessage(webSocket: WebSocket, text: String) {
- super.onMessage(webSocket, text)
-// text.writeToFile(createLogFile())
- Log.d(kTag, "onMessage: ${text.length}")
- lifecycleScope.launch(Dispatchers.Main) {
- val message = EnvironmentActivity.weakReferenceHandler.obtainMessage()
- message.what = LocaleConstant.WEBSOCKET_MESSAGE_CODE
- message.obj = text
- EnvironmentActivity.weakReferenceHandler.sendMessage(message)
- }
- }
-
- override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
- super.onFailure(webSocket, t, response)
- lifecycleScope.launch(Dispatchers.Main) {
- EnvironmentActivity.weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_DISCONNECTED_CODE)
- }
- }
- })
- httpClient.dispatcher.executorService.shutdown()
- }
- return START_STICKY
- }
-
- override fun onDestroy() {
- super.onDestroy()
- webSocket?.close(1000, null)
- Log.d(kTag, "onDestroy: WebSocketMessageService")
- }
-
- override fun onBind(intent: Intent?): IBinder? {
- return null
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt
index 3676eab..725b743 100644
--- a/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt
+++ b/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt
@@ -27,7 +27,6 @@
import com.casic.br.operationsite.utils.DeviceType
import com.casic.br.operationsite.utils.RuntimeCache
import com.casic.br.operationsite.view.check.DisclosureActivity
-import com.casic.br.operationsite.vm.AlarmViewModel
import com.casic.br.operationsite.vm.DeviceViewModel
import com.casic.br.operationsite.vm.LoginViewModel
import com.casic.br.operationsite.vm.WorkSiteViewModel
@@ -50,7 +49,6 @@
private lateinit var workSiteViewModel: WorkSiteViewModel
private lateinit var deviceViewModel: DeviceViewModel
private lateinit var loginViewModel: LoginViewModel
- private lateinit var alarmViewModel: AlarmViewModel
private lateinit var userHelmetCode: String
private val polygonOptions by lazy { PolygonOptions() }
private val latLngArray: MutableList = ArrayList()
@@ -254,11 +252,6 @@
navigatePageTo()
}
}
-
- alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java]
- alarmViewModel.alarmState.observe(this) {
-
- }
}
override fun onMarkerClick(marker: Marker?): Boolean {
@@ -394,15 +387,6 @@
navigatePageTo()
}
- binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked ->
- val state = if (isChecked) {
- "1"
- } else {
- "0"
- }
- alarmViewModel.changeAlarmState("", state)
- }
-
binding.reloadDataView.setOnClickListener {
aMap.clear()
@@ -416,7 +400,6 @@
override fun onResume() {
super.onResume()
binding.mapView.onResume()
- alarmViewModel.getAlarmDetail(this, "")
}
override fun onPause() {
diff --git a/app/src/main/java/com/casic/br/operationsite/view/check/EnvironmentActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/check/EnvironmentActivity.kt
index cec8a1f..50bb949 100644
--- a/app/src/main/java/com/casic/br/operationsite/view/check/EnvironmentActivity.kt
+++ b/app/src/main/java/com/casic/br/operationsite/view/check/EnvironmentActivity.kt
@@ -1,6 +1,5 @@
package com.casic.br.operationsite.view.check
-import android.content.Intent
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Bundle
@@ -9,10 +8,10 @@
import android.util.Base64
import android.util.Log
import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.lifecycleScope
import com.casic.br.operationsite.R
import com.casic.br.operationsite.databinding.ActivityEnvironmentBinding
import com.casic.br.operationsite.extensions.initImmersionBar
-import com.casic.br.operationsite.service.WebSocketMessageService
import com.casic.br.operationsite.utils.LocaleConstant
import com.casic.br.operationsite.utils.RuntimeCache
import com.casic.br.operationsite.utils.tcp.ISocketListener
@@ -28,25 +27,30 @@
import com.pengxh.kt.lite.utils.ActivityStackManager
import com.pengxh.kt.lite.utils.WeakReferenceHandler
import com.pengxh.kt.lite.widget.TitleBarView
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import okhttp3.Response
+import okhttp3.WebSocket
+import okhttp3.WebSocketListener
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.util.Timer
import java.util.TimerTask
+import java.util.concurrent.TimeUnit
class EnvironmentActivity : KotlinBaseActivity(), Handler.Callback {
- companion object {
- lateinit var weakReferenceHandler: WeakReferenceHandler
- }
-
private val kTag = "EnvironmentActivity"
private val context = this
private val timeFormat by lazy { SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA) }
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
private lateinit var constructionCheckViewModel: ConstructionCheckViewModel
private lateinit var workSiteViewModel: WorkSiteViewModel
private lateinit var timer: Timer
- private var isStart = false
+ private lateinit var webSocket: WebSocket
private var isFirstConfirm = false
private var isSecondConfirm = false
private var isThirdConfirm = false
@@ -54,7 +58,7 @@
override fun handleMessage(msg: Message): Boolean {
when (msg.what) {
- LocaleConstant.WEBSOCKET_CONNECTED_CODE -> "WebSocket连接成功".show(this)
+ LocaleConstant.WEBSOCKET_CONNECTED_CODE -> "AI连接成功".show(this)
LocaleConstant.WEBSOCKET_MESSAGE_CODE -> {
try {
@@ -68,7 +72,7 @@
}
}
- LocaleConstant.WEBSOCKET_DISCONNECTED_CODE -> "WebSocket连接失败".show(this)
+ LocaleConstant.WEBSOCKET_DISCONNECTED_CODE -> "AI连接失败".show(this)
}
return true
}
@@ -80,7 +84,6 @@
return@setOnClickListener
}
SocketManager.get.send(LocaleConstant.START_ENV_COMMAND)
- isStart = true
constructionCheckViewModel.setCurrentPhase(this, "before_operation_environment")
//播放RTSP流
binding.videoView.setVideoURI(Uri.parse("rtsp://192.168.10.137:554"))
@@ -131,13 +134,20 @@
}
isThirdConfirm = true
}
+
+ binding.endEnvCheckButton.setOnClickListener {
+ if (SocketManager.get.statusCode != ISocketListener.STATUS_CONNECT_SUCCESS) {
+ "指令发送失败,请确认是否处于同一网段".show(this)
+ return@setOnClickListener
+ }
+ SocketManager.get.send(LocaleConstant.END_ENV_COMMAND)
+ navigatePageTo()
+ }
}
override fun initOnCreate(savedInstanceState: Bundle?) {
ActivityStackManager.addActivity(this)
- startService(Intent(this, WebSocketMessageService::class.java))
-
weakReferenceHandler = WeakReferenceHandler(this)
constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java]
@@ -146,6 +156,8 @@
binding.videoView.start()
}
+ startWebSocket()
+
timer = Timer()
workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java]
timer.schedule(object : TimerTask() {
@@ -178,6 +190,45 @@
}
}
+ private fun startWebSocket() {
+ //初始化WebSocket
+ val httpClient = OkHttpClient.Builder()
+ .connectTimeout(10, TimeUnit.SECONDS)
+ .readTimeout(10, TimeUnit.SECONDS)
+ .writeTimeout(10, TimeUnit.SECONDS)
+ .build()
+ lifecycleScope.launch(Dispatchers.IO) {
+ val request = Request.Builder().url("ws://192.168.10.142:8765").build()
+ httpClient.newWebSocket(request, object : WebSocketListener() {
+ override fun onOpen(webSocket: WebSocket, response: Response) {
+ super.onOpen(webSocket, response)
+ this@EnvironmentActivity.webSocket = webSocket
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_CONNECTED_CODE)
+ }
+ }
+
+ override fun onMessage(webSocket: WebSocket, text: String) {
+ super.onMessage(webSocket, text)
+ lifecycleScope.launch(Dispatchers.Main) {
+ val message = weakReferenceHandler.obtainMessage()
+ message.what = LocaleConstant.WEBSOCKET_MESSAGE_CODE
+ message.obj = text
+ weakReferenceHandler.sendMessage(message)
+ }
+ }
+
+ override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
+ super.onFailure(webSocket, t, response)
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_DISCONNECTED_CODE)
+ }
+ }
+ })
+ httpClient.dispatcher.executorService.shutdown()
+ }
+ }
+
override fun initViewBinding(): ActivityEnvironmentBinding {
return ActivityEnvironmentBinding.inflate(layoutInflater)
}
@@ -203,5 +254,6 @@
super.onDestroy()
binding.videoView.suspend()
timer.cancel()
+ webSocket.close(1000, null)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/operationsite/view/check/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/check/GuardiansActivity.kt
new file mode 100644
index 0000000..8805701
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/check/GuardiansActivity.kt
@@ -0,0 +1,270 @@
+package com.casic.br.operationsite.view.check
+
+import android.graphics.BitmapFactory
+import android.net.Uri
+import android.os.Bundle
+import android.os.Handler
+import android.os.Message
+import android.util.Base64
+import android.util.Log
+import android.view.View
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.lifecycleScope
+import com.casic.br.operationsite.R
+import com.casic.br.operationsite.databinding.ActivityGuardiansBinding
+import com.casic.br.operationsite.extensions.initImmersionBar
+import com.casic.br.operationsite.utils.LocaleConstant
+import com.casic.br.operationsite.utils.RuntimeCache
+import com.casic.br.operationsite.view.BigImageActivity
+import com.casic.br.operationsite.view.MainActivity
+import com.casic.br.operationsite.vm.AlarmViewModel
+import com.casic.br.operationsite.vm.ConstructionCheckViewModel
+import com.casic.br.operationsite.vm.WorkSiteViewModel
+import com.pengxh.kt.lite.adapter.EditableImageAdapter
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets
+import com.pengxh.kt.lite.extensions.createImageFileDir
+import com.pengxh.kt.lite.extensions.dp2px
+import com.pengxh.kt.lite.extensions.getScreenWidth
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.saveImage
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.extensions.toJson
+import com.pengxh.kt.lite.utils.ActivityStackManager
+import com.pengxh.kt.lite.utils.WeakReferenceHandler
+import com.pengxh.kt.lite.widget.TitleBarView
+import com.pengxh.kt.lite.widget.dialog.AlertControlDialog
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import okhttp3.Response
+import okhttp3.WebSocket
+import okhttp3.WebSocketListener
+import java.text.SimpleDateFormat
+import java.util.Date
+import java.util.Locale
+import java.util.Timer
+import java.util.TimerTask
+import java.util.concurrent.TimeUnit
+
+class GuardiansActivity : KotlinBaseActivity(), Handler.Callback {
+
+ private val kTag = "GuardiansActivity"
+ private val context = this
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
+ private lateinit var alarmViewModel: AlarmViewModel
+ private lateinit var constructionCheckViewModel: ConstructionCheckViewModel
+ private lateinit var workSiteViewModel: WorkSiteViewModel
+ private lateinit var imageAdapter: EditableImageAdapter
+ private lateinit var webSocket: WebSocket
+ private lateinit var timer: Timer
+ private val timeFormat by lazy { SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA) }
+ private val marginOffset by lazy { 1.dp2px(this) }
+ private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径
+
+ override fun initEvent() {
+ binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked ->
+ val state = if (isChecked) {
+ "1"
+ } else {
+ "0"
+ }
+ alarmViewModel.changeAlarmState("", state)
+ }
+
+ binding.setVideoRegionButton.setOnClickListener {
+ val region = binding.regionView.getConfirmedPoints()
+ Log.d(kTag, region.toJson())
+
+ constructionCheckViewModel.setVideoRegion(this, region)
+ }
+
+ binding.startVideoCheckButton.setOnClickListener {
+ constructionCheckViewModel.setCurrentPhase(this, "in_operation")
+ }
+
+ imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener {
+ override fun onAddImageClick() {
+ "当前模式不支持手动添加图片".show(context)
+ }
+
+ override fun onItemClick(position: Int) {
+ if (recyclerViewImages[position].isEmpty()) {
+ "图片加载失败,无法查看大图".show(context)
+ } else {
+ navigatePageTo(position, recyclerViewImages)
+ }
+ }
+
+ override fun onItemLongClick(view: View?, position: Int) {
+ recyclerViewImages.removeAt(position)
+ imageAdapter.notifyDataSetChanged()
+ }
+ })
+
+ binding.endTaskButton.setOnClickListener {
+ AlertControlDialog.Builder().setContext(this).setTitle("温馨提示")
+ .setMessage("确定结束此次施工?").setNegativeButton("取消").setPositiveButton("确定")
+ .setOnDialogButtonClickListener(object :
+ AlertControlDialog.OnDialogButtonClickListener {
+ override fun onConfirmClick() {
+ ActivityStackManager.finishActivity(DisclosureActivity::class.java)
+ ActivityStackManager.finishActivity(EnvironmentActivity::class.java)
+ ActivityStackManager.finishActivity(SuppliesActivity::class.java)
+ navigatePageTo()
+ finish()
+ }
+
+ override fun onCancelClick() {}
+ }).build().show()
+ }
+ }
+
+ override fun initOnCreate(savedInstanceState: Bundle?) {
+ ActivityStackManager.addActivity(this)
+
+ weakReferenceHandler = WeakReferenceHandler(this)
+ //播放RTSP流
+ binding.videoView.setVideoURI(Uri.parse("rtsp://192.168.10.137:554"))
+ binding.videoView.setOnPreparedListener {
+ binding.videoView.requestFocus()
+ binding.videoView.start()
+ }
+ startWebSocket()
+
+ alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java]
+ alarmViewModel.alarmState.observe(this) {
+
+ }
+
+ constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java]
+ constructionCheckViewModel.postResult.observe(this) {
+ if (it.code == 200) {
+ "区域配置成功".show(this)
+ }
+ }
+
+ //左右边距
+ val viewWidth = getScreenWidth() - (15 + 15).dp2px(this)
+ imageAdapter = EditableImageAdapter(this, recyclerViewImages, viewWidth, 3, 3)
+ binding.recyclerView.addItemDecoration(
+ RecyclerViewItemOffsets(marginOffset, marginOffset, marginOffset, marginOffset)
+ )
+ binding.recyclerView.adapter = imageAdapter
+
+ timer = Timer()
+ workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java]
+ timer.schedule(object : TimerTask() {
+ override fun run() {
+ workSiteViewModel.getWorkers(context, RuntimeCache.projectId)
+ }
+ }, 0, 5000)
+ workSiteViewModel.workerResult.observe(this) {
+ if (it.code == 200) {
+ it.data.forEach { worker ->
+ if (worker.lat.isNotBlank() && worker.lng.isNotBlank()) {
+ val value =
+ "CO:${worker.co}ppm, CH4:${worker.gas}ppm, H2S:${worker.co}ppm, O2:${worker.o2}%VOL"
+ Log.d(kTag, "value: $value")
+ }
+ }
+ }
+ }
+ }
+
+ override fun handleMessage(msg: Message): Boolean {
+ when (msg.what) {
+ LocaleConstant.WEBSOCKET_CONNECTED_CODE -> "AI连接成功".show(this)
+
+ LocaleConstant.WEBSOCKET_MESSAGE_CODE -> {
+ try {
+ val bitmapArray = Base64.decode((msg.obj as String), Base64.DEFAULT)
+ val bitmap = BitmapFactory.decodeByteArray(bitmapArray, 0, bitmapArray.size)
+ val imagePath = "/${createImageFileDir()}/IMG${timeFormat.format(Date())}.png"
+ Log.d(kTag, "imagePath: $imagePath")
+ bitmap.saveImage(imagePath)
+ if (recyclerViewImages.size == 3) {
+ recyclerViewImages.removeAt(0)
+ }
+ recyclerViewImages.add(imagePath)
+ imageAdapter.notifyDataSetChanged()
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ LocaleConstant.WEBSOCKET_DISCONNECTED_CODE -> "AI连接失败".show(this)
+ }
+ return true
+ }
+
+ private fun startWebSocket() {
+ //初始化WebSocket
+ val httpClient = OkHttpClient.Builder().connectTimeout(10, TimeUnit.SECONDS)
+ .readTimeout(10, TimeUnit.SECONDS).writeTimeout(10, TimeUnit.SECONDS).build()
+ lifecycleScope.launch(Dispatchers.IO) {
+ val request = Request.Builder().url("ws://192.168.10.142:8765").build()
+ httpClient.newWebSocket(request, object : WebSocketListener() {
+ override fun onOpen(webSocket: WebSocket, response: Response) {
+ super.onOpen(webSocket, response)
+ this@GuardiansActivity.webSocket = webSocket
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_CONNECTED_CODE)
+ }
+ }
+
+ override fun onMessage(webSocket: WebSocket, text: String) {
+ super.onMessage(webSocket, text)
+ lifecycleScope.launch(Dispatchers.Main) {
+ val message = weakReferenceHandler.obtainMessage()
+ message.what = LocaleConstant.WEBSOCKET_MESSAGE_CODE
+ message.obj = text
+ weakReferenceHandler.sendMessage(message)
+ }
+ }
+
+ override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
+ super.onFailure(webSocket, t, response)
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_DISCONNECTED_CODE)
+ }
+ }
+ })
+ httpClient.dispatcher.executorService.shutdown()
+ }
+ }
+
+ override fun initViewBinding(): ActivityGuardiansBinding {
+ return ActivityGuardiansBinding.inflate(layoutInflater)
+ }
+
+ override fun observeRequestState() {
+
+ }
+
+ override fun setupTopBarLayout() {
+ binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor)
+ binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener {
+ override fun onLeftClick() {
+ finish()
+ }
+
+ override fun onRightClick() {
+
+ }
+ })
+ }
+
+ override fun onResume() {
+ super.onResume()
+ alarmViewModel.getAlarmState(this)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ binding.videoView.suspend()
+ timer.cancel()
+ webSocket.close(1000, null)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/operationsite/view/check/SuppliesActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/check/SuppliesActivity.kt
new file mode 100644
index 0000000..ba387fc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/check/SuppliesActivity.kt
@@ -0,0 +1,233 @@
+package com.casic.br.operationsite.view.check
+
+import android.content.Intent
+import android.graphics.BitmapFactory
+import android.net.Uri
+import android.os.Bundle
+import android.os.Handler
+import android.os.Message
+import android.util.Base64
+import android.util.Log
+import android.view.View
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.lifecycleScope
+import com.casic.br.operationsite.R
+import com.casic.br.operationsite.databinding.ActivitySuppliesBinding
+import com.casic.br.operationsite.extensions.initImmersionBar
+import com.casic.br.operationsite.utils.LocaleConstant
+import com.casic.br.operationsite.utils.tcp.ISocketListener
+import com.casic.br.operationsite.utils.tcp.SocketManager
+import com.casic.br.operationsite.view.BigImageActivity
+import com.casic.br.operationsite.view.HelmetVideoActivity
+import com.casic.br.operationsite.vm.ConstructionCheckViewModel
+import com.pengxh.kt.lite.adapter.EditableImageAdapter
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets
+import com.pengxh.kt.lite.extensions.createImageFileDir
+import com.pengxh.kt.lite.extensions.dp2px
+import com.pengxh.kt.lite.extensions.getScreenWidth
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.saveImage
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.utils.ActivityStackManager
+import com.pengxh.kt.lite.utils.WeakReferenceHandler
+import com.pengxh.kt.lite.widget.TitleBarView
+import com.pengxh.kt.lite.widget.dialog.AlertControlDialog
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import okhttp3.Response
+import okhttp3.WebSocket
+import okhttp3.WebSocketListener
+import java.text.SimpleDateFormat
+import java.util.Date
+import java.util.Locale
+import java.util.concurrent.TimeUnit
+
+class SuppliesActivity : KotlinBaseActivity(), Handler.Callback {
+
+ private val kTag = "SuppliesActivity"
+ private val context = this
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
+ private lateinit var constructionCheckViewModel: ConstructionCheckViewModel
+ private lateinit var imageAdapter: EditableImageAdapter
+ private lateinit var webSocket: WebSocket
+ private val timeFormat by lazy { SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA) }
+ private val marginOffset by lazy { 1.dp2px(this) }
+ private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径
+
+ override fun initEvent() {
+ binding.startSuppliesCheckButton.setOnClickListener {
+ if (SocketManager.get.statusCode != ISocketListener.STATUS_CONNECT_SUCCESS) {
+ "指令发送失败,请确认是否处于同一网段".show(this)
+ return@setOnClickListener
+ }
+ SocketManager.get.send(LocaleConstant.START_SUPPLIES_COMMAND)
+ }
+
+ binding.startVideoCheckButton.setOnClickListener {
+ startVideoLauncher.launch(Intent(this, HelmetVideoActivity::class.java))
+ }
+
+ imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener {
+ override fun onAddImageClick() {
+ "当前模式不支持手动添加图片".show(context)
+ }
+
+ override fun onItemClick(position: Int) {
+ if (recyclerViewImages[position].isEmpty()) {
+ "图片加载失败,无法查看大图".show(context)
+ } else {
+ navigatePageTo(position, recyclerViewImages)
+ }
+ }
+
+ override fun onItemLongClick(view: View?, position: Int) {
+ recyclerViewImages.removeAt(position)
+ imageAdapter.notifyDataSetChanged()
+ }
+ })
+ }
+
+ private val startVideoLauncher = registerForActivityResult(
+ ActivityResultContracts.StartActivityForResult()
+ ) {
+ Log.d(kTag, "startVideoLauncher: ")
+ SocketManager.get.send(LocaleConstant.START_VIDEO_COMMAND)
+ constructionCheckViewModel.setCurrentPhase(this, "before_operation_protection")
+ //播放RTSP流
+ binding.videoView.setVideoURI(Uri.parse("rtsp://192.168.10.137:554"))
+ }
+
+ private fun startWebSocket() {
+ //初始化WebSocket
+ val httpClient = OkHttpClient.Builder()
+ .connectTimeout(10, TimeUnit.SECONDS)
+ .readTimeout(10, TimeUnit.SECONDS)
+ .writeTimeout(10, TimeUnit.SECONDS)
+ .build()
+ lifecycleScope.launch(Dispatchers.IO) {
+ val request = Request.Builder().url("ws://192.168.10.142:8765").build()
+ httpClient.newWebSocket(request, object : WebSocketListener() {
+ override fun onOpen(webSocket: WebSocket, response: Response) {
+ super.onOpen(webSocket, response)
+ this@SuppliesActivity.webSocket = webSocket
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_CONNECTED_CODE)
+ }
+ }
+
+ override fun onMessage(webSocket: WebSocket, text: String) {
+ super.onMessage(webSocket, text)
+ lifecycleScope.launch(Dispatchers.Main) {
+ val message = weakReferenceHandler.obtainMessage()
+ message.what = LocaleConstant.WEBSOCKET_MESSAGE_CODE
+ message.obj = text
+ weakReferenceHandler.sendMessage(message)
+ }
+ }
+
+ override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
+ super.onFailure(webSocket, t, response)
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_DISCONNECTED_CODE)
+ }
+ }
+ })
+ httpClient.dispatcher.executorService.shutdown()
+ }
+ }
+
+ override fun initOnCreate(savedInstanceState: Bundle?) {
+ ActivityStackManager.addActivity(this)
+
+ weakReferenceHandler = WeakReferenceHandler(this)
+ constructionCheckViewModel =
+ ViewModelProvider(this)[ConstructionCheckViewModel::class.java]
+
+ startWebSocket()
+
+ binding.videoView.setOnPreparedListener {
+ binding.videoView.requestFocus()
+ binding.videoView.start()
+ }
+
+ //左右边距
+ val viewWidth = getScreenWidth() - (15 + 15).dp2px(this)
+ imageAdapter = EditableImageAdapter(this, recyclerViewImages, viewWidth, 6, 3)
+ binding.recyclerView.addItemDecoration(
+ RecyclerViewItemOffsets(marginOffset, marginOffset, marginOffset, marginOffset)
+ )
+ binding.recyclerView.adapter = imageAdapter
+ }
+
+ override fun handleMessage(msg: Message): Boolean {
+ when (msg.what) {
+ LocaleConstant.WEBSOCKET_CONNECTED_CODE -> "AI连接成功".show(this)
+
+ LocaleConstant.WEBSOCKET_MESSAGE_CODE -> {
+ try {
+ val bitmapArray = Base64.decode((msg.obj as String), Base64.DEFAULT)
+ val bitmap = BitmapFactory.decodeByteArray(bitmapArray, 0, bitmapArray.size)
+ val imagePath =
+ "/${createImageFileDir()}/IMG${timeFormat.format(Date())}.png"
+ Log.d(kTag, "imagePath: $imagePath")
+ bitmap.saveImage(imagePath)
+ recyclerViewImages.add(imagePath)
+ imageAdapter.notifyDataSetChanged()
+
+ if (recyclerViewImages.size == 6) {
+ AlertControlDialog.Builder()
+ .setContext(this)
+ .setTitle("温馨提示")
+ .setMessage("检测到施工前劳保用品准备完毕,是否开始施工?")
+ .setNegativeButton("取消")
+ .setPositiveButton("确定")
+ .setOnDialogButtonClickListener(object :
+ AlertControlDialog.OnDialogButtonClickListener {
+ override fun onConfirmClick() {
+ navigatePageTo()
+ }
+
+ override fun onCancelClick() {}
+ }).build().show()
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ LocaleConstant.WEBSOCKET_DISCONNECTED_CODE -> "AI连接失败".show(this)
+ }
+ return true
+ }
+
+ override fun initViewBinding(): ActivitySuppliesBinding {
+ return ActivitySuppliesBinding.inflate(layoutInflater)
+ }
+
+ override fun observeRequestState() {
+
+ }
+
+ override fun setupTopBarLayout() {
+ binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor)
+ binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener {
+ override fun onLeftClick() {
+ finish()
+ }
+
+ override fun onRightClick() {
+
+ }
+ })
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ binding.videoView.suspend()
+ webSocket.close(1000, null)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 7e82efe..7bce4f3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -68,6 +68,7 @@
+
@@ -94,7 +95,6 @@
-
diff --git a/app/src/main/java/com/casic/br/operationsite/service/WebSocketMessageService.kt b/app/src/main/java/com/casic/br/operationsite/service/WebSocketMessageService.kt
deleted file mode 100644
index 52e08a8..0000000
--- a/app/src/main/java/com/casic/br/operationsite/service/WebSocketMessageService.kt
+++ /dev/null
@@ -1,92 +0,0 @@
-package com.casic.br.operationsite.service
-
-import android.app.Service
-import android.content.Intent
-import android.os.IBinder
-import android.util.Log
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.LifecycleOwner
-import androidx.lifecycle.LifecycleRegistry
-import androidx.lifecycle.lifecycleScope
-import com.casic.br.operationsite.utils.LocaleConstant
-import com.casic.br.operationsite.view.check.EnvironmentActivity
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-import okhttp3.OkHttpClient
-import okhttp3.Request
-import okhttp3.Response
-import okhttp3.WebSocket
-import okhttp3.WebSocketListener
-import java.util.concurrent.TimeUnit
-
-
-class WebSocketMessageService : Service(), LifecycleOwner {
-
- private val kTag = "WebSocketMessageService"
- private val registry = LifecycleRegistry(this)
-
- override fun getLifecycle(): Lifecycle {
- return registry
- }
-
- private var webSocket: WebSocket? = null
-
- override fun onCreate() {
- super.onCreate()
- Log.d(kTag, "onCreate: WebSocketMessageService")
- }
-
- override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
- //初始化WebSocket
- val httpClient = OkHttpClient.Builder()
- .connectTimeout(10, TimeUnit.SECONDS)
- .readTimeout(10, TimeUnit.SECONDS)
- .writeTimeout(10, TimeUnit.SECONDS)
- .build()
- lifecycleScope.launch(Dispatchers.IO) {
- val request = Request.Builder()
- .url("ws://192.168.10.142:8765")
- .build()
- httpClient.newWebSocket(request, object : WebSocketListener() {
- override fun onOpen(webSocket: WebSocket, response: Response) {
- super.onOpen(webSocket, response)
- this@WebSocketMessageService.webSocket = webSocket
- lifecycleScope.launch(Dispatchers.Main) {
- EnvironmentActivity.weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_CONNECTED_CODE)
- }
- }
-
- override fun onMessage(webSocket: WebSocket, text: String) {
- super.onMessage(webSocket, text)
-// text.writeToFile(createLogFile())
- Log.d(kTag, "onMessage: ${text.length}")
- lifecycleScope.launch(Dispatchers.Main) {
- val message = EnvironmentActivity.weakReferenceHandler.obtainMessage()
- message.what = LocaleConstant.WEBSOCKET_MESSAGE_CODE
- message.obj = text
- EnvironmentActivity.weakReferenceHandler.sendMessage(message)
- }
- }
-
- override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
- super.onFailure(webSocket, t, response)
- lifecycleScope.launch(Dispatchers.Main) {
- EnvironmentActivity.weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_DISCONNECTED_CODE)
- }
- }
- })
- httpClient.dispatcher.executorService.shutdown()
- }
- return START_STICKY
- }
-
- override fun onDestroy() {
- super.onDestroy()
- webSocket?.close(1000, null)
- Log.d(kTag, "onDestroy: WebSocketMessageService")
- }
-
- override fun onBind(intent: Intent?): IBinder? {
- return null
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt
index 3676eab..725b743 100644
--- a/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt
+++ b/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt
@@ -27,7 +27,6 @@
import com.casic.br.operationsite.utils.DeviceType
import com.casic.br.operationsite.utils.RuntimeCache
import com.casic.br.operationsite.view.check.DisclosureActivity
-import com.casic.br.operationsite.vm.AlarmViewModel
import com.casic.br.operationsite.vm.DeviceViewModel
import com.casic.br.operationsite.vm.LoginViewModel
import com.casic.br.operationsite.vm.WorkSiteViewModel
@@ -50,7 +49,6 @@
private lateinit var workSiteViewModel: WorkSiteViewModel
private lateinit var deviceViewModel: DeviceViewModel
private lateinit var loginViewModel: LoginViewModel
- private lateinit var alarmViewModel: AlarmViewModel
private lateinit var userHelmetCode: String
private val polygonOptions by lazy { PolygonOptions() }
private val latLngArray: MutableList = ArrayList()
@@ -254,11 +252,6 @@
navigatePageTo()
}
}
-
- alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java]
- alarmViewModel.alarmState.observe(this) {
-
- }
}
override fun onMarkerClick(marker: Marker?): Boolean {
@@ -394,15 +387,6 @@
navigatePageTo()
}
- binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked ->
- val state = if (isChecked) {
- "1"
- } else {
- "0"
- }
- alarmViewModel.changeAlarmState("", state)
- }
-
binding.reloadDataView.setOnClickListener {
aMap.clear()
@@ -416,7 +400,6 @@
override fun onResume() {
super.onResume()
binding.mapView.onResume()
- alarmViewModel.getAlarmDetail(this, "")
}
override fun onPause() {
diff --git a/app/src/main/java/com/casic/br/operationsite/view/check/EnvironmentActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/check/EnvironmentActivity.kt
index cec8a1f..50bb949 100644
--- a/app/src/main/java/com/casic/br/operationsite/view/check/EnvironmentActivity.kt
+++ b/app/src/main/java/com/casic/br/operationsite/view/check/EnvironmentActivity.kt
@@ -1,6 +1,5 @@
package com.casic.br.operationsite.view.check
-import android.content.Intent
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Bundle
@@ -9,10 +8,10 @@
import android.util.Base64
import android.util.Log
import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.lifecycleScope
import com.casic.br.operationsite.R
import com.casic.br.operationsite.databinding.ActivityEnvironmentBinding
import com.casic.br.operationsite.extensions.initImmersionBar
-import com.casic.br.operationsite.service.WebSocketMessageService
import com.casic.br.operationsite.utils.LocaleConstant
import com.casic.br.operationsite.utils.RuntimeCache
import com.casic.br.operationsite.utils.tcp.ISocketListener
@@ -28,25 +27,30 @@
import com.pengxh.kt.lite.utils.ActivityStackManager
import com.pengxh.kt.lite.utils.WeakReferenceHandler
import com.pengxh.kt.lite.widget.TitleBarView
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import okhttp3.Response
+import okhttp3.WebSocket
+import okhttp3.WebSocketListener
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.util.Timer
import java.util.TimerTask
+import java.util.concurrent.TimeUnit
class EnvironmentActivity : KotlinBaseActivity(), Handler.Callback {
- companion object {
- lateinit var weakReferenceHandler: WeakReferenceHandler
- }
-
private val kTag = "EnvironmentActivity"
private val context = this
private val timeFormat by lazy { SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA) }
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
private lateinit var constructionCheckViewModel: ConstructionCheckViewModel
private lateinit var workSiteViewModel: WorkSiteViewModel
private lateinit var timer: Timer
- private var isStart = false
+ private lateinit var webSocket: WebSocket
private var isFirstConfirm = false
private var isSecondConfirm = false
private var isThirdConfirm = false
@@ -54,7 +58,7 @@
override fun handleMessage(msg: Message): Boolean {
when (msg.what) {
- LocaleConstant.WEBSOCKET_CONNECTED_CODE -> "WebSocket连接成功".show(this)
+ LocaleConstant.WEBSOCKET_CONNECTED_CODE -> "AI连接成功".show(this)
LocaleConstant.WEBSOCKET_MESSAGE_CODE -> {
try {
@@ -68,7 +72,7 @@
}
}
- LocaleConstant.WEBSOCKET_DISCONNECTED_CODE -> "WebSocket连接失败".show(this)
+ LocaleConstant.WEBSOCKET_DISCONNECTED_CODE -> "AI连接失败".show(this)
}
return true
}
@@ -80,7 +84,6 @@
return@setOnClickListener
}
SocketManager.get.send(LocaleConstant.START_ENV_COMMAND)
- isStart = true
constructionCheckViewModel.setCurrentPhase(this, "before_operation_environment")
//播放RTSP流
binding.videoView.setVideoURI(Uri.parse("rtsp://192.168.10.137:554"))
@@ -131,13 +134,20 @@
}
isThirdConfirm = true
}
+
+ binding.endEnvCheckButton.setOnClickListener {
+ if (SocketManager.get.statusCode != ISocketListener.STATUS_CONNECT_SUCCESS) {
+ "指令发送失败,请确认是否处于同一网段".show(this)
+ return@setOnClickListener
+ }
+ SocketManager.get.send(LocaleConstant.END_ENV_COMMAND)
+ navigatePageTo()
+ }
}
override fun initOnCreate(savedInstanceState: Bundle?) {
ActivityStackManager.addActivity(this)
- startService(Intent(this, WebSocketMessageService::class.java))
-
weakReferenceHandler = WeakReferenceHandler(this)
constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java]
@@ -146,6 +156,8 @@
binding.videoView.start()
}
+ startWebSocket()
+
timer = Timer()
workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java]
timer.schedule(object : TimerTask() {
@@ -178,6 +190,45 @@
}
}
+ private fun startWebSocket() {
+ //初始化WebSocket
+ val httpClient = OkHttpClient.Builder()
+ .connectTimeout(10, TimeUnit.SECONDS)
+ .readTimeout(10, TimeUnit.SECONDS)
+ .writeTimeout(10, TimeUnit.SECONDS)
+ .build()
+ lifecycleScope.launch(Dispatchers.IO) {
+ val request = Request.Builder().url("ws://192.168.10.142:8765").build()
+ httpClient.newWebSocket(request, object : WebSocketListener() {
+ override fun onOpen(webSocket: WebSocket, response: Response) {
+ super.onOpen(webSocket, response)
+ this@EnvironmentActivity.webSocket = webSocket
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_CONNECTED_CODE)
+ }
+ }
+
+ override fun onMessage(webSocket: WebSocket, text: String) {
+ super.onMessage(webSocket, text)
+ lifecycleScope.launch(Dispatchers.Main) {
+ val message = weakReferenceHandler.obtainMessage()
+ message.what = LocaleConstant.WEBSOCKET_MESSAGE_CODE
+ message.obj = text
+ weakReferenceHandler.sendMessage(message)
+ }
+ }
+
+ override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
+ super.onFailure(webSocket, t, response)
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_DISCONNECTED_CODE)
+ }
+ }
+ })
+ httpClient.dispatcher.executorService.shutdown()
+ }
+ }
+
override fun initViewBinding(): ActivityEnvironmentBinding {
return ActivityEnvironmentBinding.inflate(layoutInflater)
}
@@ -203,5 +254,6 @@
super.onDestroy()
binding.videoView.suspend()
timer.cancel()
+ webSocket.close(1000, null)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/operationsite/view/check/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/check/GuardiansActivity.kt
new file mode 100644
index 0000000..8805701
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/check/GuardiansActivity.kt
@@ -0,0 +1,270 @@
+package com.casic.br.operationsite.view.check
+
+import android.graphics.BitmapFactory
+import android.net.Uri
+import android.os.Bundle
+import android.os.Handler
+import android.os.Message
+import android.util.Base64
+import android.util.Log
+import android.view.View
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.lifecycleScope
+import com.casic.br.operationsite.R
+import com.casic.br.operationsite.databinding.ActivityGuardiansBinding
+import com.casic.br.operationsite.extensions.initImmersionBar
+import com.casic.br.operationsite.utils.LocaleConstant
+import com.casic.br.operationsite.utils.RuntimeCache
+import com.casic.br.operationsite.view.BigImageActivity
+import com.casic.br.operationsite.view.MainActivity
+import com.casic.br.operationsite.vm.AlarmViewModel
+import com.casic.br.operationsite.vm.ConstructionCheckViewModel
+import com.casic.br.operationsite.vm.WorkSiteViewModel
+import com.pengxh.kt.lite.adapter.EditableImageAdapter
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets
+import com.pengxh.kt.lite.extensions.createImageFileDir
+import com.pengxh.kt.lite.extensions.dp2px
+import com.pengxh.kt.lite.extensions.getScreenWidth
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.saveImage
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.extensions.toJson
+import com.pengxh.kt.lite.utils.ActivityStackManager
+import com.pengxh.kt.lite.utils.WeakReferenceHandler
+import com.pengxh.kt.lite.widget.TitleBarView
+import com.pengxh.kt.lite.widget.dialog.AlertControlDialog
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import okhttp3.Response
+import okhttp3.WebSocket
+import okhttp3.WebSocketListener
+import java.text.SimpleDateFormat
+import java.util.Date
+import java.util.Locale
+import java.util.Timer
+import java.util.TimerTask
+import java.util.concurrent.TimeUnit
+
+class GuardiansActivity : KotlinBaseActivity(), Handler.Callback {
+
+ private val kTag = "GuardiansActivity"
+ private val context = this
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
+ private lateinit var alarmViewModel: AlarmViewModel
+ private lateinit var constructionCheckViewModel: ConstructionCheckViewModel
+ private lateinit var workSiteViewModel: WorkSiteViewModel
+ private lateinit var imageAdapter: EditableImageAdapter
+ private lateinit var webSocket: WebSocket
+ private lateinit var timer: Timer
+ private val timeFormat by lazy { SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA) }
+ private val marginOffset by lazy { 1.dp2px(this) }
+ private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径
+
+ override fun initEvent() {
+ binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked ->
+ val state = if (isChecked) {
+ "1"
+ } else {
+ "0"
+ }
+ alarmViewModel.changeAlarmState("", state)
+ }
+
+ binding.setVideoRegionButton.setOnClickListener {
+ val region = binding.regionView.getConfirmedPoints()
+ Log.d(kTag, region.toJson())
+
+ constructionCheckViewModel.setVideoRegion(this, region)
+ }
+
+ binding.startVideoCheckButton.setOnClickListener {
+ constructionCheckViewModel.setCurrentPhase(this, "in_operation")
+ }
+
+ imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener {
+ override fun onAddImageClick() {
+ "当前模式不支持手动添加图片".show(context)
+ }
+
+ override fun onItemClick(position: Int) {
+ if (recyclerViewImages[position].isEmpty()) {
+ "图片加载失败,无法查看大图".show(context)
+ } else {
+ navigatePageTo(position, recyclerViewImages)
+ }
+ }
+
+ override fun onItemLongClick(view: View?, position: Int) {
+ recyclerViewImages.removeAt(position)
+ imageAdapter.notifyDataSetChanged()
+ }
+ })
+
+ binding.endTaskButton.setOnClickListener {
+ AlertControlDialog.Builder().setContext(this).setTitle("温馨提示")
+ .setMessage("确定结束此次施工?").setNegativeButton("取消").setPositiveButton("确定")
+ .setOnDialogButtonClickListener(object :
+ AlertControlDialog.OnDialogButtonClickListener {
+ override fun onConfirmClick() {
+ ActivityStackManager.finishActivity(DisclosureActivity::class.java)
+ ActivityStackManager.finishActivity(EnvironmentActivity::class.java)
+ ActivityStackManager.finishActivity(SuppliesActivity::class.java)
+ navigatePageTo()
+ finish()
+ }
+
+ override fun onCancelClick() {}
+ }).build().show()
+ }
+ }
+
+ override fun initOnCreate(savedInstanceState: Bundle?) {
+ ActivityStackManager.addActivity(this)
+
+ weakReferenceHandler = WeakReferenceHandler(this)
+ //播放RTSP流
+ binding.videoView.setVideoURI(Uri.parse("rtsp://192.168.10.137:554"))
+ binding.videoView.setOnPreparedListener {
+ binding.videoView.requestFocus()
+ binding.videoView.start()
+ }
+ startWebSocket()
+
+ alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java]
+ alarmViewModel.alarmState.observe(this) {
+
+ }
+
+ constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java]
+ constructionCheckViewModel.postResult.observe(this) {
+ if (it.code == 200) {
+ "区域配置成功".show(this)
+ }
+ }
+
+ //左右边距
+ val viewWidth = getScreenWidth() - (15 + 15).dp2px(this)
+ imageAdapter = EditableImageAdapter(this, recyclerViewImages, viewWidth, 3, 3)
+ binding.recyclerView.addItemDecoration(
+ RecyclerViewItemOffsets(marginOffset, marginOffset, marginOffset, marginOffset)
+ )
+ binding.recyclerView.adapter = imageAdapter
+
+ timer = Timer()
+ workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java]
+ timer.schedule(object : TimerTask() {
+ override fun run() {
+ workSiteViewModel.getWorkers(context, RuntimeCache.projectId)
+ }
+ }, 0, 5000)
+ workSiteViewModel.workerResult.observe(this) {
+ if (it.code == 200) {
+ it.data.forEach { worker ->
+ if (worker.lat.isNotBlank() && worker.lng.isNotBlank()) {
+ val value =
+ "CO:${worker.co}ppm, CH4:${worker.gas}ppm, H2S:${worker.co}ppm, O2:${worker.o2}%VOL"
+ Log.d(kTag, "value: $value")
+ }
+ }
+ }
+ }
+ }
+
+ override fun handleMessage(msg: Message): Boolean {
+ when (msg.what) {
+ LocaleConstant.WEBSOCKET_CONNECTED_CODE -> "AI连接成功".show(this)
+
+ LocaleConstant.WEBSOCKET_MESSAGE_CODE -> {
+ try {
+ val bitmapArray = Base64.decode((msg.obj as String), Base64.DEFAULT)
+ val bitmap = BitmapFactory.decodeByteArray(bitmapArray, 0, bitmapArray.size)
+ val imagePath = "/${createImageFileDir()}/IMG${timeFormat.format(Date())}.png"
+ Log.d(kTag, "imagePath: $imagePath")
+ bitmap.saveImage(imagePath)
+ if (recyclerViewImages.size == 3) {
+ recyclerViewImages.removeAt(0)
+ }
+ recyclerViewImages.add(imagePath)
+ imageAdapter.notifyDataSetChanged()
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ LocaleConstant.WEBSOCKET_DISCONNECTED_CODE -> "AI连接失败".show(this)
+ }
+ return true
+ }
+
+ private fun startWebSocket() {
+ //初始化WebSocket
+ val httpClient = OkHttpClient.Builder().connectTimeout(10, TimeUnit.SECONDS)
+ .readTimeout(10, TimeUnit.SECONDS).writeTimeout(10, TimeUnit.SECONDS).build()
+ lifecycleScope.launch(Dispatchers.IO) {
+ val request = Request.Builder().url("ws://192.168.10.142:8765").build()
+ httpClient.newWebSocket(request, object : WebSocketListener() {
+ override fun onOpen(webSocket: WebSocket, response: Response) {
+ super.onOpen(webSocket, response)
+ this@GuardiansActivity.webSocket = webSocket
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_CONNECTED_CODE)
+ }
+ }
+
+ override fun onMessage(webSocket: WebSocket, text: String) {
+ super.onMessage(webSocket, text)
+ lifecycleScope.launch(Dispatchers.Main) {
+ val message = weakReferenceHandler.obtainMessage()
+ message.what = LocaleConstant.WEBSOCKET_MESSAGE_CODE
+ message.obj = text
+ weakReferenceHandler.sendMessage(message)
+ }
+ }
+
+ override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
+ super.onFailure(webSocket, t, response)
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_DISCONNECTED_CODE)
+ }
+ }
+ })
+ httpClient.dispatcher.executorService.shutdown()
+ }
+ }
+
+ override fun initViewBinding(): ActivityGuardiansBinding {
+ return ActivityGuardiansBinding.inflate(layoutInflater)
+ }
+
+ override fun observeRequestState() {
+
+ }
+
+ override fun setupTopBarLayout() {
+ binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor)
+ binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener {
+ override fun onLeftClick() {
+ finish()
+ }
+
+ override fun onRightClick() {
+
+ }
+ })
+ }
+
+ override fun onResume() {
+ super.onResume()
+ alarmViewModel.getAlarmState(this)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ binding.videoView.suspend()
+ timer.cancel()
+ webSocket.close(1000, null)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/operationsite/view/check/SuppliesActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/check/SuppliesActivity.kt
new file mode 100644
index 0000000..ba387fc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/check/SuppliesActivity.kt
@@ -0,0 +1,233 @@
+package com.casic.br.operationsite.view.check
+
+import android.content.Intent
+import android.graphics.BitmapFactory
+import android.net.Uri
+import android.os.Bundle
+import android.os.Handler
+import android.os.Message
+import android.util.Base64
+import android.util.Log
+import android.view.View
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.lifecycleScope
+import com.casic.br.operationsite.R
+import com.casic.br.operationsite.databinding.ActivitySuppliesBinding
+import com.casic.br.operationsite.extensions.initImmersionBar
+import com.casic.br.operationsite.utils.LocaleConstant
+import com.casic.br.operationsite.utils.tcp.ISocketListener
+import com.casic.br.operationsite.utils.tcp.SocketManager
+import com.casic.br.operationsite.view.BigImageActivity
+import com.casic.br.operationsite.view.HelmetVideoActivity
+import com.casic.br.operationsite.vm.ConstructionCheckViewModel
+import com.pengxh.kt.lite.adapter.EditableImageAdapter
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets
+import com.pengxh.kt.lite.extensions.createImageFileDir
+import com.pengxh.kt.lite.extensions.dp2px
+import com.pengxh.kt.lite.extensions.getScreenWidth
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.saveImage
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.utils.ActivityStackManager
+import com.pengxh.kt.lite.utils.WeakReferenceHandler
+import com.pengxh.kt.lite.widget.TitleBarView
+import com.pengxh.kt.lite.widget.dialog.AlertControlDialog
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import okhttp3.Response
+import okhttp3.WebSocket
+import okhttp3.WebSocketListener
+import java.text.SimpleDateFormat
+import java.util.Date
+import java.util.Locale
+import java.util.concurrent.TimeUnit
+
+class SuppliesActivity : KotlinBaseActivity(), Handler.Callback {
+
+ private val kTag = "SuppliesActivity"
+ private val context = this
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
+ private lateinit var constructionCheckViewModel: ConstructionCheckViewModel
+ private lateinit var imageAdapter: EditableImageAdapter
+ private lateinit var webSocket: WebSocket
+ private val timeFormat by lazy { SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA) }
+ private val marginOffset by lazy { 1.dp2px(this) }
+ private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径
+
+ override fun initEvent() {
+ binding.startSuppliesCheckButton.setOnClickListener {
+ if (SocketManager.get.statusCode != ISocketListener.STATUS_CONNECT_SUCCESS) {
+ "指令发送失败,请确认是否处于同一网段".show(this)
+ return@setOnClickListener
+ }
+ SocketManager.get.send(LocaleConstant.START_SUPPLIES_COMMAND)
+ }
+
+ binding.startVideoCheckButton.setOnClickListener {
+ startVideoLauncher.launch(Intent(this, HelmetVideoActivity::class.java))
+ }
+
+ imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener {
+ override fun onAddImageClick() {
+ "当前模式不支持手动添加图片".show(context)
+ }
+
+ override fun onItemClick(position: Int) {
+ if (recyclerViewImages[position].isEmpty()) {
+ "图片加载失败,无法查看大图".show(context)
+ } else {
+ navigatePageTo(position, recyclerViewImages)
+ }
+ }
+
+ override fun onItemLongClick(view: View?, position: Int) {
+ recyclerViewImages.removeAt(position)
+ imageAdapter.notifyDataSetChanged()
+ }
+ })
+ }
+
+ private val startVideoLauncher = registerForActivityResult(
+ ActivityResultContracts.StartActivityForResult()
+ ) {
+ Log.d(kTag, "startVideoLauncher: ")
+ SocketManager.get.send(LocaleConstant.START_VIDEO_COMMAND)
+ constructionCheckViewModel.setCurrentPhase(this, "before_operation_protection")
+ //播放RTSP流
+ binding.videoView.setVideoURI(Uri.parse("rtsp://192.168.10.137:554"))
+ }
+
+ private fun startWebSocket() {
+ //初始化WebSocket
+ val httpClient = OkHttpClient.Builder()
+ .connectTimeout(10, TimeUnit.SECONDS)
+ .readTimeout(10, TimeUnit.SECONDS)
+ .writeTimeout(10, TimeUnit.SECONDS)
+ .build()
+ lifecycleScope.launch(Dispatchers.IO) {
+ val request = Request.Builder().url("ws://192.168.10.142:8765").build()
+ httpClient.newWebSocket(request, object : WebSocketListener() {
+ override fun onOpen(webSocket: WebSocket, response: Response) {
+ super.onOpen(webSocket, response)
+ this@SuppliesActivity.webSocket = webSocket
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_CONNECTED_CODE)
+ }
+ }
+
+ override fun onMessage(webSocket: WebSocket, text: String) {
+ super.onMessage(webSocket, text)
+ lifecycleScope.launch(Dispatchers.Main) {
+ val message = weakReferenceHandler.obtainMessage()
+ message.what = LocaleConstant.WEBSOCKET_MESSAGE_CODE
+ message.obj = text
+ weakReferenceHandler.sendMessage(message)
+ }
+ }
+
+ override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
+ super.onFailure(webSocket, t, response)
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_DISCONNECTED_CODE)
+ }
+ }
+ })
+ httpClient.dispatcher.executorService.shutdown()
+ }
+ }
+
+ override fun initOnCreate(savedInstanceState: Bundle?) {
+ ActivityStackManager.addActivity(this)
+
+ weakReferenceHandler = WeakReferenceHandler(this)
+ constructionCheckViewModel =
+ ViewModelProvider(this)[ConstructionCheckViewModel::class.java]
+
+ startWebSocket()
+
+ binding.videoView.setOnPreparedListener {
+ binding.videoView.requestFocus()
+ binding.videoView.start()
+ }
+
+ //左右边距
+ val viewWidth = getScreenWidth() - (15 + 15).dp2px(this)
+ imageAdapter = EditableImageAdapter(this, recyclerViewImages, viewWidth, 6, 3)
+ binding.recyclerView.addItemDecoration(
+ RecyclerViewItemOffsets(marginOffset, marginOffset, marginOffset, marginOffset)
+ )
+ binding.recyclerView.adapter = imageAdapter
+ }
+
+ override fun handleMessage(msg: Message): Boolean {
+ when (msg.what) {
+ LocaleConstant.WEBSOCKET_CONNECTED_CODE -> "AI连接成功".show(this)
+
+ LocaleConstant.WEBSOCKET_MESSAGE_CODE -> {
+ try {
+ val bitmapArray = Base64.decode((msg.obj as String), Base64.DEFAULT)
+ val bitmap = BitmapFactory.decodeByteArray(bitmapArray, 0, bitmapArray.size)
+ val imagePath =
+ "/${createImageFileDir()}/IMG${timeFormat.format(Date())}.png"
+ Log.d(kTag, "imagePath: $imagePath")
+ bitmap.saveImage(imagePath)
+ recyclerViewImages.add(imagePath)
+ imageAdapter.notifyDataSetChanged()
+
+ if (recyclerViewImages.size == 6) {
+ AlertControlDialog.Builder()
+ .setContext(this)
+ .setTitle("温馨提示")
+ .setMessage("检测到施工前劳保用品准备完毕,是否开始施工?")
+ .setNegativeButton("取消")
+ .setPositiveButton("确定")
+ .setOnDialogButtonClickListener(object :
+ AlertControlDialog.OnDialogButtonClickListener {
+ override fun onConfirmClick() {
+ navigatePageTo()
+ }
+
+ override fun onCancelClick() {}
+ }).build().show()
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ LocaleConstant.WEBSOCKET_DISCONNECTED_CODE -> "AI连接失败".show(this)
+ }
+ return true
+ }
+
+ override fun initViewBinding(): ActivitySuppliesBinding {
+ return ActivitySuppliesBinding.inflate(layoutInflater)
+ }
+
+ override fun observeRequestState() {
+
+ }
+
+ override fun setupTopBarLayout() {
+ binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor)
+ binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener {
+ override fun onLeftClick() {
+ finish()
+ }
+
+ override fun onRightClick() {
+
+ }
+ })
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ binding.videoView.suspend()
+ webSocket.close(1000, null)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_guardians.xml b/app/src/main/res/layout/activity_guardians.xml
new file mode 100644
index 0000000..5403809
--- /dev/null
+++ b/app/src/main/res/layout/activity_guardians.xml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 7e82efe..7bce4f3 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -68,6 +68,7 @@
+
@@ -94,7 +95,6 @@
-
diff --git a/app/src/main/java/com/casic/br/operationsite/service/WebSocketMessageService.kt b/app/src/main/java/com/casic/br/operationsite/service/WebSocketMessageService.kt
deleted file mode 100644
index 52e08a8..0000000
--- a/app/src/main/java/com/casic/br/operationsite/service/WebSocketMessageService.kt
+++ /dev/null
@@ -1,92 +0,0 @@
-package com.casic.br.operationsite.service
-
-import android.app.Service
-import android.content.Intent
-import android.os.IBinder
-import android.util.Log
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.LifecycleOwner
-import androidx.lifecycle.LifecycleRegistry
-import androidx.lifecycle.lifecycleScope
-import com.casic.br.operationsite.utils.LocaleConstant
-import com.casic.br.operationsite.view.check.EnvironmentActivity
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-import okhttp3.OkHttpClient
-import okhttp3.Request
-import okhttp3.Response
-import okhttp3.WebSocket
-import okhttp3.WebSocketListener
-import java.util.concurrent.TimeUnit
-
-
-class WebSocketMessageService : Service(), LifecycleOwner {
-
- private val kTag = "WebSocketMessageService"
- private val registry = LifecycleRegistry(this)
-
- override fun getLifecycle(): Lifecycle {
- return registry
- }
-
- private var webSocket: WebSocket? = null
-
- override fun onCreate() {
- super.onCreate()
- Log.d(kTag, "onCreate: WebSocketMessageService")
- }
-
- override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
- //初始化WebSocket
- val httpClient = OkHttpClient.Builder()
- .connectTimeout(10, TimeUnit.SECONDS)
- .readTimeout(10, TimeUnit.SECONDS)
- .writeTimeout(10, TimeUnit.SECONDS)
- .build()
- lifecycleScope.launch(Dispatchers.IO) {
- val request = Request.Builder()
- .url("ws://192.168.10.142:8765")
- .build()
- httpClient.newWebSocket(request, object : WebSocketListener() {
- override fun onOpen(webSocket: WebSocket, response: Response) {
- super.onOpen(webSocket, response)
- this@WebSocketMessageService.webSocket = webSocket
- lifecycleScope.launch(Dispatchers.Main) {
- EnvironmentActivity.weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_CONNECTED_CODE)
- }
- }
-
- override fun onMessage(webSocket: WebSocket, text: String) {
- super.onMessage(webSocket, text)
-// text.writeToFile(createLogFile())
- Log.d(kTag, "onMessage: ${text.length}")
- lifecycleScope.launch(Dispatchers.Main) {
- val message = EnvironmentActivity.weakReferenceHandler.obtainMessage()
- message.what = LocaleConstant.WEBSOCKET_MESSAGE_CODE
- message.obj = text
- EnvironmentActivity.weakReferenceHandler.sendMessage(message)
- }
- }
-
- override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
- super.onFailure(webSocket, t, response)
- lifecycleScope.launch(Dispatchers.Main) {
- EnvironmentActivity.weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_DISCONNECTED_CODE)
- }
- }
- })
- httpClient.dispatcher.executorService.shutdown()
- }
- return START_STICKY
- }
-
- override fun onDestroy() {
- super.onDestroy()
- webSocket?.close(1000, null)
- Log.d(kTag, "onDestroy: WebSocketMessageService")
- }
-
- override fun onBind(intent: Intent?): IBinder? {
- return null
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt
index 3676eab..725b743 100644
--- a/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt
+++ b/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt
@@ -27,7 +27,6 @@
import com.casic.br.operationsite.utils.DeviceType
import com.casic.br.operationsite.utils.RuntimeCache
import com.casic.br.operationsite.view.check.DisclosureActivity
-import com.casic.br.operationsite.vm.AlarmViewModel
import com.casic.br.operationsite.vm.DeviceViewModel
import com.casic.br.operationsite.vm.LoginViewModel
import com.casic.br.operationsite.vm.WorkSiteViewModel
@@ -50,7 +49,6 @@
private lateinit var workSiteViewModel: WorkSiteViewModel
private lateinit var deviceViewModel: DeviceViewModel
private lateinit var loginViewModel: LoginViewModel
- private lateinit var alarmViewModel: AlarmViewModel
private lateinit var userHelmetCode: String
private val polygonOptions by lazy { PolygonOptions() }
private val latLngArray: MutableList = ArrayList()
@@ -254,11 +252,6 @@
navigatePageTo()
}
}
-
- alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java]
- alarmViewModel.alarmState.observe(this) {
-
- }
}
override fun onMarkerClick(marker: Marker?): Boolean {
@@ -394,15 +387,6 @@
navigatePageTo()
}
- binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked ->
- val state = if (isChecked) {
- "1"
- } else {
- "0"
- }
- alarmViewModel.changeAlarmState("", state)
- }
-
binding.reloadDataView.setOnClickListener {
aMap.clear()
@@ -416,7 +400,6 @@
override fun onResume() {
super.onResume()
binding.mapView.onResume()
- alarmViewModel.getAlarmDetail(this, "")
}
override fun onPause() {
diff --git a/app/src/main/java/com/casic/br/operationsite/view/check/EnvironmentActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/check/EnvironmentActivity.kt
index cec8a1f..50bb949 100644
--- a/app/src/main/java/com/casic/br/operationsite/view/check/EnvironmentActivity.kt
+++ b/app/src/main/java/com/casic/br/operationsite/view/check/EnvironmentActivity.kt
@@ -1,6 +1,5 @@
package com.casic.br.operationsite.view.check
-import android.content.Intent
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Bundle
@@ -9,10 +8,10 @@
import android.util.Base64
import android.util.Log
import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.lifecycleScope
import com.casic.br.operationsite.R
import com.casic.br.operationsite.databinding.ActivityEnvironmentBinding
import com.casic.br.operationsite.extensions.initImmersionBar
-import com.casic.br.operationsite.service.WebSocketMessageService
import com.casic.br.operationsite.utils.LocaleConstant
import com.casic.br.operationsite.utils.RuntimeCache
import com.casic.br.operationsite.utils.tcp.ISocketListener
@@ -28,25 +27,30 @@
import com.pengxh.kt.lite.utils.ActivityStackManager
import com.pengxh.kt.lite.utils.WeakReferenceHandler
import com.pengxh.kt.lite.widget.TitleBarView
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import okhttp3.Response
+import okhttp3.WebSocket
+import okhttp3.WebSocketListener
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.util.Timer
import java.util.TimerTask
+import java.util.concurrent.TimeUnit
class EnvironmentActivity : KotlinBaseActivity(), Handler.Callback {
- companion object {
- lateinit var weakReferenceHandler: WeakReferenceHandler
- }
-
private val kTag = "EnvironmentActivity"
private val context = this
private val timeFormat by lazy { SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA) }
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
private lateinit var constructionCheckViewModel: ConstructionCheckViewModel
private lateinit var workSiteViewModel: WorkSiteViewModel
private lateinit var timer: Timer
- private var isStart = false
+ private lateinit var webSocket: WebSocket
private var isFirstConfirm = false
private var isSecondConfirm = false
private var isThirdConfirm = false
@@ -54,7 +58,7 @@
override fun handleMessage(msg: Message): Boolean {
when (msg.what) {
- LocaleConstant.WEBSOCKET_CONNECTED_CODE -> "WebSocket连接成功".show(this)
+ LocaleConstant.WEBSOCKET_CONNECTED_CODE -> "AI连接成功".show(this)
LocaleConstant.WEBSOCKET_MESSAGE_CODE -> {
try {
@@ -68,7 +72,7 @@
}
}
- LocaleConstant.WEBSOCKET_DISCONNECTED_CODE -> "WebSocket连接失败".show(this)
+ LocaleConstant.WEBSOCKET_DISCONNECTED_CODE -> "AI连接失败".show(this)
}
return true
}
@@ -80,7 +84,6 @@
return@setOnClickListener
}
SocketManager.get.send(LocaleConstant.START_ENV_COMMAND)
- isStart = true
constructionCheckViewModel.setCurrentPhase(this, "before_operation_environment")
//播放RTSP流
binding.videoView.setVideoURI(Uri.parse("rtsp://192.168.10.137:554"))
@@ -131,13 +134,20 @@
}
isThirdConfirm = true
}
+
+ binding.endEnvCheckButton.setOnClickListener {
+ if (SocketManager.get.statusCode != ISocketListener.STATUS_CONNECT_SUCCESS) {
+ "指令发送失败,请确认是否处于同一网段".show(this)
+ return@setOnClickListener
+ }
+ SocketManager.get.send(LocaleConstant.END_ENV_COMMAND)
+ navigatePageTo()
+ }
}
override fun initOnCreate(savedInstanceState: Bundle?) {
ActivityStackManager.addActivity(this)
- startService(Intent(this, WebSocketMessageService::class.java))
-
weakReferenceHandler = WeakReferenceHandler(this)
constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java]
@@ -146,6 +156,8 @@
binding.videoView.start()
}
+ startWebSocket()
+
timer = Timer()
workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java]
timer.schedule(object : TimerTask() {
@@ -178,6 +190,45 @@
}
}
+ private fun startWebSocket() {
+ //初始化WebSocket
+ val httpClient = OkHttpClient.Builder()
+ .connectTimeout(10, TimeUnit.SECONDS)
+ .readTimeout(10, TimeUnit.SECONDS)
+ .writeTimeout(10, TimeUnit.SECONDS)
+ .build()
+ lifecycleScope.launch(Dispatchers.IO) {
+ val request = Request.Builder().url("ws://192.168.10.142:8765").build()
+ httpClient.newWebSocket(request, object : WebSocketListener() {
+ override fun onOpen(webSocket: WebSocket, response: Response) {
+ super.onOpen(webSocket, response)
+ this@EnvironmentActivity.webSocket = webSocket
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_CONNECTED_CODE)
+ }
+ }
+
+ override fun onMessage(webSocket: WebSocket, text: String) {
+ super.onMessage(webSocket, text)
+ lifecycleScope.launch(Dispatchers.Main) {
+ val message = weakReferenceHandler.obtainMessage()
+ message.what = LocaleConstant.WEBSOCKET_MESSAGE_CODE
+ message.obj = text
+ weakReferenceHandler.sendMessage(message)
+ }
+ }
+
+ override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
+ super.onFailure(webSocket, t, response)
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_DISCONNECTED_CODE)
+ }
+ }
+ })
+ httpClient.dispatcher.executorService.shutdown()
+ }
+ }
+
override fun initViewBinding(): ActivityEnvironmentBinding {
return ActivityEnvironmentBinding.inflate(layoutInflater)
}
@@ -203,5 +254,6 @@
super.onDestroy()
binding.videoView.suspend()
timer.cancel()
+ webSocket.close(1000, null)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/operationsite/view/check/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/check/GuardiansActivity.kt
new file mode 100644
index 0000000..8805701
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/check/GuardiansActivity.kt
@@ -0,0 +1,270 @@
+package com.casic.br.operationsite.view.check
+
+import android.graphics.BitmapFactory
+import android.net.Uri
+import android.os.Bundle
+import android.os.Handler
+import android.os.Message
+import android.util.Base64
+import android.util.Log
+import android.view.View
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.lifecycleScope
+import com.casic.br.operationsite.R
+import com.casic.br.operationsite.databinding.ActivityGuardiansBinding
+import com.casic.br.operationsite.extensions.initImmersionBar
+import com.casic.br.operationsite.utils.LocaleConstant
+import com.casic.br.operationsite.utils.RuntimeCache
+import com.casic.br.operationsite.view.BigImageActivity
+import com.casic.br.operationsite.view.MainActivity
+import com.casic.br.operationsite.vm.AlarmViewModel
+import com.casic.br.operationsite.vm.ConstructionCheckViewModel
+import com.casic.br.operationsite.vm.WorkSiteViewModel
+import com.pengxh.kt.lite.adapter.EditableImageAdapter
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets
+import com.pengxh.kt.lite.extensions.createImageFileDir
+import com.pengxh.kt.lite.extensions.dp2px
+import com.pengxh.kt.lite.extensions.getScreenWidth
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.saveImage
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.extensions.toJson
+import com.pengxh.kt.lite.utils.ActivityStackManager
+import com.pengxh.kt.lite.utils.WeakReferenceHandler
+import com.pengxh.kt.lite.widget.TitleBarView
+import com.pengxh.kt.lite.widget.dialog.AlertControlDialog
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import okhttp3.Response
+import okhttp3.WebSocket
+import okhttp3.WebSocketListener
+import java.text.SimpleDateFormat
+import java.util.Date
+import java.util.Locale
+import java.util.Timer
+import java.util.TimerTask
+import java.util.concurrent.TimeUnit
+
+class GuardiansActivity : KotlinBaseActivity(), Handler.Callback {
+
+ private val kTag = "GuardiansActivity"
+ private val context = this
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
+ private lateinit var alarmViewModel: AlarmViewModel
+ private lateinit var constructionCheckViewModel: ConstructionCheckViewModel
+ private lateinit var workSiteViewModel: WorkSiteViewModel
+ private lateinit var imageAdapter: EditableImageAdapter
+ private lateinit var webSocket: WebSocket
+ private lateinit var timer: Timer
+ private val timeFormat by lazy { SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA) }
+ private val marginOffset by lazy { 1.dp2px(this) }
+ private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径
+
+ override fun initEvent() {
+ binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked ->
+ val state = if (isChecked) {
+ "1"
+ } else {
+ "0"
+ }
+ alarmViewModel.changeAlarmState("", state)
+ }
+
+ binding.setVideoRegionButton.setOnClickListener {
+ val region = binding.regionView.getConfirmedPoints()
+ Log.d(kTag, region.toJson())
+
+ constructionCheckViewModel.setVideoRegion(this, region)
+ }
+
+ binding.startVideoCheckButton.setOnClickListener {
+ constructionCheckViewModel.setCurrentPhase(this, "in_operation")
+ }
+
+ imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener {
+ override fun onAddImageClick() {
+ "当前模式不支持手动添加图片".show(context)
+ }
+
+ override fun onItemClick(position: Int) {
+ if (recyclerViewImages[position].isEmpty()) {
+ "图片加载失败,无法查看大图".show(context)
+ } else {
+ navigatePageTo(position, recyclerViewImages)
+ }
+ }
+
+ override fun onItemLongClick(view: View?, position: Int) {
+ recyclerViewImages.removeAt(position)
+ imageAdapter.notifyDataSetChanged()
+ }
+ })
+
+ binding.endTaskButton.setOnClickListener {
+ AlertControlDialog.Builder().setContext(this).setTitle("温馨提示")
+ .setMessage("确定结束此次施工?").setNegativeButton("取消").setPositiveButton("确定")
+ .setOnDialogButtonClickListener(object :
+ AlertControlDialog.OnDialogButtonClickListener {
+ override fun onConfirmClick() {
+ ActivityStackManager.finishActivity(DisclosureActivity::class.java)
+ ActivityStackManager.finishActivity(EnvironmentActivity::class.java)
+ ActivityStackManager.finishActivity(SuppliesActivity::class.java)
+ navigatePageTo()
+ finish()
+ }
+
+ override fun onCancelClick() {}
+ }).build().show()
+ }
+ }
+
+ override fun initOnCreate(savedInstanceState: Bundle?) {
+ ActivityStackManager.addActivity(this)
+
+ weakReferenceHandler = WeakReferenceHandler(this)
+ //播放RTSP流
+ binding.videoView.setVideoURI(Uri.parse("rtsp://192.168.10.137:554"))
+ binding.videoView.setOnPreparedListener {
+ binding.videoView.requestFocus()
+ binding.videoView.start()
+ }
+ startWebSocket()
+
+ alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java]
+ alarmViewModel.alarmState.observe(this) {
+
+ }
+
+ constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java]
+ constructionCheckViewModel.postResult.observe(this) {
+ if (it.code == 200) {
+ "区域配置成功".show(this)
+ }
+ }
+
+ //左右边距
+ val viewWidth = getScreenWidth() - (15 + 15).dp2px(this)
+ imageAdapter = EditableImageAdapter(this, recyclerViewImages, viewWidth, 3, 3)
+ binding.recyclerView.addItemDecoration(
+ RecyclerViewItemOffsets(marginOffset, marginOffset, marginOffset, marginOffset)
+ )
+ binding.recyclerView.adapter = imageAdapter
+
+ timer = Timer()
+ workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java]
+ timer.schedule(object : TimerTask() {
+ override fun run() {
+ workSiteViewModel.getWorkers(context, RuntimeCache.projectId)
+ }
+ }, 0, 5000)
+ workSiteViewModel.workerResult.observe(this) {
+ if (it.code == 200) {
+ it.data.forEach { worker ->
+ if (worker.lat.isNotBlank() && worker.lng.isNotBlank()) {
+ val value =
+ "CO:${worker.co}ppm, CH4:${worker.gas}ppm, H2S:${worker.co}ppm, O2:${worker.o2}%VOL"
+ Log.d(kTag, "value: $value")
+ }
+ }
+ }
+ }
+ }
+
+ override fun handleMessage(msg: Message): Boolean {
+ when (msg.what) {
+ LocaleConstant.WEBSOCKET_CONNECTED_CODE -> "AI连接成功".show(this)
+
+ LocaleConstant.WEBSOCKET_MESSAGE_CODE -> {
+ try {
+ val bitmapArray = Base64.decode((msg.obj as String), Base64.DEFAULT)
+ val bitmap = BitmapFactory.decodeByteArray(bitmapArray, 0, bitmapArray.size)
+ val imagePath = "/${createImageFileDir()}/IMG${timeFormat.format(Date())}.png"
+ Log.d(kTag, "imagePath: $imagePath")
+ bitmap.saveImage(imagePath)
+ if (recyclerViewImages.size == 3) {
+ recyclerViewImages.removeAt(0)
+ }
+ recyclerViewImages.add(imagePath)
+ imageAdapter.notifyDataSetChanged()
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ LocaleConstant.WEBSOCKET_DISCONNECTED_CODE -> "AI连接失败".show(this)
+ }
+ return true
+ }
+
+ private fun startWebSocket() {
+ //初始化WebSocket
+ val httpClient = OkHttpClient.Builder().connectTimeout(10, TimeUnit.SECONDS)
+ .readTimeout(10, TimeUnit.SECONDS).writeTimeout(10, TimeUnit.SECONDS).build()
+ lifecycleScope.launch(Dispatchers.IO) {
+ val request = Request.Builder().url("ws://192.168.10.142:8765").build()
+ httpClient.newWebSocket(request, object : WebSocketListener() {
+ override fun onOpen(webSocket: WebSocket, response: Response) {
+ super.onOpen(webSocket, response)
+ this@GuardiansActivity.webSocket = webSocket
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_CONNECTED_CODE)
+ }
+ }
+
+ override fun onMessage(webSocket: WebSocket, text: String) {
+ super.onMessage(webSocket, text)
+ lifecycleScope.launch(Dispatchers.Main) {
+ val message = weakReferenceHandler.obtainMessage()
+ message.what = LocaleConstant.WEBSOCKET_MESSAGE_CODE
+ message.obj = text
+ weakReferenceHandler.sendMessage(message)
+ }
+ }
+
+ override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
+ super.onFailure(webSocket, t, response)
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_DISCONNECTED_CODE)
+ }
+ }
+ })
+ httpClient.dispatcher.executorService.shutdown()
+ }
+ }
+
+ override fun initViewBinding(): ActivityGuardiansBinding {
+ return ActivityGuardiansBinding.inflate(layoutInflater)
+ }
+
+ override fun observeRequestState() {
+
+ }
+
+ override fun setupTopBarLayout() {
+ binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor)
+ binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener {
+ override fun onLeftClick() {
+ finish()
+ }
+
+ override fun onRightClick() {
+
+ }
+ })
+ }
+
+ override fun onResume() {
+ super.onResume()
+ alarmViewModel.getAlarmState(this)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ binding.videoView.suspend()
+ timer.cancel()
+ webSocket.close(1000, null)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/operationsite/view/check/SuppliesActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/check/SuppliesActivity.kt
new file mode 100644
index 0000000..ba387fc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/check/SuppliesActivity.kt
@@ -0,0 +1,233 @@
+package com.casic.br.operationsite.view.check
+
+import android.content.Intent
+import android.graphics.BitmapFactory
+import android.net.Uri
+import android.os.Bundle
+import android.os.Handler
+import android.os.Message
+import android.util.Base64
+import android.util.Log
+import android.view.View
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.lifecycleScope
+import com.casic.br.operationsite.R
+import com.casic.br.operationsite.databinding.ActivitySuppliesBinding
+import com.casic.br.operationsite.extensions.initImmersionBar
+import com.casic.br.operationsite.utils.LocaleConstant
+import com.casic.br.operationsite.utils.tcp.ISocketListener
+import com.casic.br.operationsite.utils.tcp.SocketManager
+import com.casic.br.operationsite.view.BigImageActivity
+import com.casic.br.operationsite.view.HelmetVideoActivity
+import com.casic.br.operationsite.vm.ConstructionCheckViewModel
+import com.pengxh.kt.lite.adapter.EditableImageAdapter
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets
+import com.pengxh.kt.lite.extensions.createImageFileDir
+import com.pengxh.kt.lite.extensions.dp2px
+import com.pengxh.kt.lite.extensions.getScreenWidth
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.saveImage
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.utils.ActivityStackManager
+import com.pengxh.kt.lite.utils.WeakReferenceHandler
+import com.pengxh.kt.lite.widget.TitleBarView
+import com.pengxh.kt.lite.widget.dialog.AlertControlDialog
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import okhttp3.Response
+import okhttp3.WebSocket
+import okhttp3.WebSocketListener
+import java.text.SimpleDateFormat
+import java.util.Date
+import java.util.Locale
+import java.util.concurrent.TimeUnit
+
+class SuppliesActivity : KotlinBaseActivity(), Handler.Callback {
+
+ private val kTag = "SuppliesActivity"
+ private val context = this
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
+ private lateinit var constructionCheckViewModel: ConstructionCheckViewModel
+ private lateinit var imageAdapter: EditableImageAdapter
+ private lateinit var webSocket: WebSocket
+ private val timeFormat by lazy { SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA) }
+ private val marginOffset by lazy { 1.dp2px(this) }
+ private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径
+
+ override fun initEvent() {
+ binding.startSuppliesCheckButton.setOnClickListener {
+ if (SocketManager.get.statusCode != ISocketListener.STATUS_CONNECT_SUCCESS) {
+ "指令发送失败,请确认是否处于同一网段".show(this)
+ return@setOnClickListener
+ }
+ SocketManager.get.send(LocaleConstant.START_SUPPLIES_COMMAND)
+ }
+
+ binding.startVideoCheckButton.setOnClickListener {
+ startVideoLauncher.launch(Intent(this, HelmetVideoActivity::class.java))
+ }
+
+ imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener {
+ override fun onAddImageClick() {
+ "当前模式不支持手动添加图片".show(context)
+ }
+
+ override fun onItemClick(position: Int) {
+ if (recyclerViewImages[position].isEmpty()) {
+ "图片加载失败,无法查看大图".show(context)
+ } else {
+ navigatePageTo(position, recyclerViewImages)
+ }
+ }
+
+ override fun onItemLongClick(view: View?, position: Int) {
+ recyclerViewImages.removeAt(position)
+ imageAdapter.notifyDataSetChanged()
+ }
+ })
+ }
+
+ private val startVideoLauncher = registerForActivityResult(
+ ActivityResultContracts.StartActivityForResult()
+ ) {
+ Log.d(kTag, "startVideoLauncher: ")
+ SocketManager.get.send(LocaleConstant.START_VIDEO_COMMAND)
+ constructionCheckViewModel.setCurrentPhase(this, "before_operation_protection")
+ //播放RTSP流
+ binding.videoView.setVideoURI(Uri.parse("rtsp://192.168.10.137:554"))
+ }
+
+ private fun startWebSocket() {
+ //初始化WebSocket
+ val httpClient = OkHttpClient.Builder()
+ .connectTimeout(10, TimeUnit.SECONDS)
+ .readTimeout(10, TimeUnit.SECONDS)
+ .writeTimeout(10, TimeUnit.SECONDS)
+ .build()
+ lifecycleScope.launch(Dispatchers.IO) {
+ val request = Request.Builder().url("ws://192.168.10.142:8765").build()
+ httpClient.newWebSocket(request, object : WebSocketListener() {
+ override fun onOpen(webSocket: WebSocket, response: Response) {
+ super.onOpen(webSocket, response)
+ this@SuppliesActivity.webSocket = webSocket
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_CONNECTED_CODE)
+ }
+ }
+
+ override fun onMessage(webSocket: WebSocket, text: String) {
+ super.onMessage(webSocket, text)
+ lifecycleScope.launch(Dispatchers.Main) {
+ val message = weakReferenceHandler.obtainMessage()
+ message.what = LocaleConstant.WEBSOCKET_MESSAGE_CODE
+ message.obj = text
+ weakReferenceHandler.sendMessage(message)
+ }
+ }
+
+ override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
+ super.onFailure(webSocket, t, response)
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_DISCONNECTED_CODE)
+ }
+ }
+ })
+ httpClient.dispatcher.executorService.shutdown()
+ }
+ }
+
+ override fun initOnCreate(savedInstanceState: Bundle?) {
+ ActivityStackManager.addActivity(this)
+
+ weakReferenceHandler = WeakReferenceHandler(this)
+ constructionCheckViewModel =
+ ViewModelProvider(this)[ConstructionCheckViewModel::class.java]
+
+ startWebSocket()
+
+ binding.videoView.setOnPreparedListener {
+ binding.videoView.requestFocus()
+ binding.videoView.start()
+ }
+
+ //左右边距
+ val viewWidth = getScreenWidth() - (15 + 15).dp2px(this)
+ imageAdapter = EditableImageAdapter(this, recyclerViewImages, viewWidth, 6, 3)
+ binding.recyclerView.addItemDecoration(
+ RecyclerViewItemOffsets(marginOffset, marginOffset, marginOffset, marginOffset)
+ )
+ binding.recyclerView.adapter = imageAdapter
+ }
+
+ override fun handleMessage(msg: Message): Boolean {
+ when (msg.what) {
+ LocaleConstant.WEBSOCKET_CONNECTED_CODE -> "AI连接成功".show(this)
+
+ LocaleConstant.WEBSOCKET_MESSAGE_CODE -> {
+ try {
+ val bitmapArray = Base64.decode((msg.obj as String), Base64.DEFAULT)
+ val bitmap = BitmapFactory.decodeByteArray(bitmapArray, 0, bitmapArray.size)
+ val imagePath =
+ "/${createImageFileDir()}/IMG${timeFormat.format(Date())}.png"
+ Log.d(kTag, "imagePath: $imagePath")
+ bitmap.saveImage(imagePath)
+ recyclerViewImages.add(imagePath)
+ imageAdapter.notifyDataSetChanged()
+
+ if (recyclerViewImages.size == 6) {
+ AlertControlDialog.Builder()
+ .setContext(this)
+ .setTitle("温馨提示")
+ .setMessage("检测到施工前劳保用品准备完毕,是否开始施工?")
+ .setNegativeButton("取消")
+ .setPositiveButton("确定")
+ .setOnDialogButtonClickListener(object :
+ AlertControlDialog.OnDialogButtonClickListener {
+ override fun onConfirmClick() {
+ navigatePageTo()
+ }
+
+ override fun onCancelClick() {}
+ }).build().show()
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ LocaleConstant.WEBSOCKET_DISCONNECTED_CODE -> "AI连接失败".show(this)
+ }
+ return true
+ }
+
+ override fun initViewBinding(): ActivitySuppliesBinding {
+ return ActivitySuppliesBinding.inflate(layoutInflater)
+ }
+
+ override fun observeRequestState() {
+
+ }
+
+ override fun setupTopBarLayout() {
+ binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor)
+ binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener {
+ override fun onLeftClick() {
+ finish()
+ }
+
+ override fun onRightClick() {
+
+ }
+ })
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ binding.videoView.suspend()
+ webSocket.close(1000, null)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_guardians.xml b/app/src/main/res/layout/activity_guardians.xml
new file mode 100644
index 0000000..5403809
--- /dev/null
+++ b/app/src/main/res/layout/activity_guardians.xml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_site_tab.xml b/app/src/main/res/layout/activity_site_tab.xml
index 079220e..8053288 100644
--- a/app/src/main/res/layout/activity_site_tab.xml
+++ b/app/src/main/res/layout/activity_site_tab.xml
@@ -134,13 +134,6 @@
android:text="所属道路:"
android:textSize="@dimen/sp_14" />
-
-
+
@@ -94,7 +95,6 @@
-
diff --git a/app/src/main/java/com/casic/br/operationsite/service/WebSocketMessageService.kt b/app/src/main/java/com/casic/br/operationsite/service/WebSocketMessageService.kt
deleted file mode 100644
index 52e08a8..0000000
--- a/app/src/main/java/com/casic/br/operationsite/service/WebSocketMessageService.kt
+++ /dev/null
@@ -1,92 +0,0 @@
-package com.casic.br.operationsite.service
-
-import android.app.Service
-import android.content.Intent
-import android.os.IBinder
-import android.util.Log
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.LifecycleOwner
-import androidx.lifecycle.LifecycleRegistry
-import androidx.lifecycle.lifecycleScope
-import com.casic.br.operationsite.utils.LocaleConstant
-import com.casic.br.operationsite.view.check.EnvironmentActivity
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.launch
-import okhttp3.OkHttpClient
-import okhttp3.Request
-import okhttp3.Response
-import okhttp3.WebSocket
-import okhttp3.WebSocketListener
-import java.util.concurrent.TimeUnit
-
-
-class WebSocketMessageService : Service(), LifecycleOwner {
-
- private val kTag = "WebSocketMessageService"
- private val registry = LifecycleRegistry(this)
-
- override fun getLifecycle(): Lifecycle {
- return registry
- }
-
- private var webSocket: WebSocket? = null
-
- override fun onCreate() {
- super.onCreate()
- Log.d(kTag, "onCreate: WebSocketMessageService")
- }
-
- override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
- //初始化WebSocket
- val httpClient = OkHttpClient.Builder()
- .connectTimeout(10, TimeUnit.SECONDS)
- .readTimeout(10, TimeUnit.SECONDS)
- .writeTimeout(10, TimeUnit.SECONDS)
- .build()
- lifecycleScope.launch(Dispatchers.IO) {
- val request = Request.Builder()
- .url("ws://192.168.10.142:8765")
- .build()
- httpClient.newWebSocket(request, object : WebSocketListener() {
- override fun onOpen(webSocket: WebSocket, response: Response) {
- super.onOpen(webSocket, response)
- this@WebSocketMessageService.webSocket = webSocket
- lifecycleScope.launch(Dispatchers.Main) {
- EnvironmentActivity.weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_CONNECTED_CODE)
- }
- }
-
- override fun onMessage(webSocket: WebSocket, text: String) {
- super.onMessage(webSocket, text)
-// text.writeToFile(createLogFile())
- Log.d(kTag, "onMessage: ${text.length}")
- lifecycleScope.launch(Dispatchers.Main) {
- val message = EnvironmentActivity.weakReferenceHandler.obtainMessage()
- message.what = LocaleConstant.WEBSOCKET_MESSAGE_CODE
- message.obj = text
- EnvironmentActivity.weakReferenceHandler.sendMessage(message)
- }
- }
-
- override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
- super.onFailure(webSocket, t, response)
- lifecycleScope.launch(Dispatchers.Main) {
- EnvironmentActivity.weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_DISCONNECTED_CODE)
- }
- }
- })
- httpClient.dispatcher.executorService.shutdown()
- }
- return START_STICKY
- }
-
- override fun onDestroy() {
- super.onDestroy()
- webSocket?.close(1000, null)
- Log.d(kTag, "onDestroy: WebSocketMessageService")
- }
-
- override fun onBind(intent: Intent?): IBinder? {
- return null
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt
index 3676eab..725b743 100644
--- a/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt
+++ b/app/src/main/java/com/casic/br/operationsite/view/WorkSiteTabActivity.kt
@@ -27,7 +27,6 @@
import com.casic.br.operationsite.utils.DeviceType
import com.casic.br.operationsite.utils.RuntimeCache
import com.casic.br.operationsite.view.check.DisclosureActivity
-import com.casic.br.operationsite.vm.AlarmViewModel
import com.casic.br.operationsite.vm.DeviceViewModel
import com.casic.br.operationsite.vm.LoginViewModel
import com.casic.br.operationsite.vm.WorkSiteViewModel
@@ -50,7 +49,6 @@
private lateinit var workSiteViewModel: WorkSiteViewModel
private lateinit var deviceViewModel: DeviceViewModel
private lateinit var loginViewModel: LoginViewModel
- private lateinit var alarmViewModel: AlarmViewModel
private lateinit var userHelmetCode: String
private val polygonOptions by lazy { PolygonOptions() }
private val latLngArray: MutableList = ArrayList()
@@ -254,11 +252,6 @@
navigatePageTo()
}
}
-
- alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java]
- alarmViewModel.alarmState.observe(this) {
-
- }
}
override fun onMarkerClick(marker: Marker?): Boolean {
@@ -394,15 +387,6 @@
navigatePageTo()
}
- binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked ->
- val state = if (isChecked) {
- "1"
- } else {
- "0"
- }
- alarmViewModel.changeAlarmState("", state)
- }
-
binding.reloadDataView.setOnClickListener {
aMap.clear()
@@ -416,7 +400,6 @@
override fun onResume() {
super.onResume()
binding.mapView.onResume()
- alarmViewModel.getAlarmDetail(this, "")
}
override fun onPause() {
diff --git a/app/src/main/java/com/casic/br/operationsite/view/check/EnvironmentActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/check/EnvironmentActivity.kt
index cec8a1f..50bb949 100644
--- a/app/src/main/java/com/casic/br/operationsite/view/check/EnvironmentActivity.kt
+++ b/app/src/main/java/com/casic/br/operationsite/view/check/EnvironmentActivity.kt
@@ -1,6 +1,5 @@
package com.casic.br.operationsite.view.check
-import android.content.Intent
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Bundle
@@ -9,10 +8,10 @@
import android.util.Base64
import android.util.Log
import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.lifecycleScope
import com.casic.br.operationsite.R
import com.casic.br.operationsite.databinding.ActivityEnvironmentBinding
import com.casic.br.operationsite.extensions.initImmersionBar
-import com.casic.br.operationsite.service.WebSocketMessageService
import com.casic.br.operationsite.utils.LocaleConstant
import com.casic.br.operationsite.utils.RuntimeCache
import com.casic.br.operationsite.utils.tcp.ISocketListener
@@ -28,25 +27,30 @@
import com.pengxh.kt.lite.utils.ActivityStackManager
import com.pengxh.kt.lite.utils.WeakReferenceHandler
import com.pengxh.kt.lite.widget.TitleBarView
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import okhttp3.Response
+import okhttp3.WebSocket
+import okhttp3.WebSocketListener
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import java.util.Timer
import java.util.TimerTask
+import java.util.concurrent.TimeUnit
class EnvironmentActivity : KotlinBaseActivity(), Handler.Callback {
- companion object {
- lateinit var weakReferenceHandler: WeakReferenceHandler
- }
-
private val kTag = "EnvironmentActivity"
private val context = this
private val timeFormat by lazy { SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA) }
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
private lateinit var constructionCheckViewModel: ConstructionCheckViewModel
private lateinit var workSiteViewModel: WorkSiteViewModel
private lateinit var timer: Timer
- private var isStart = false
+ private lateinit var webSocket: WebSocket
private var isFirstConfirm = false
private var isSecondConfirm = false
private var isThirdConfirm = false
@@ -54,7 +58,7 @@
override fun handleMessage(msg: Message): Boolean {
when (msg.what) {
- LocaleConstant.WEBSOCKET_CONNECTED_CODE -> "WebSocket连接成功".show(this)
+ LocaleConstant.WEBSOCKET_CONNECTED_CODE -> "AI连接成功".show(this)
LocaleConstant.WEBSOCKET_MESSAGE_CODE -> {
try {
@@ -68,7 +72,7 @@
}
}
- LocaleConstant.WEBSOCKET_DISCONNECTED_CODE -> "WebSocket连接失败".show(this)
+ LocaleConstant.WEBSOCKET_DISCONNECTED_CODE -> "AI连接失败".show(this)
}
return true
}
@@ -80,7 +84,6 @@
return@setOnClickListener
}
SocketManager.get.send(LocaleConstant.START_ENV_COMMAND)
- isStart = true
constructionCheckViewModel.setCurrentPhase(this, "before_operation_environment")
//播放RTSP流
binding.videoView.setVideoURI(Uri.parse("rtsp://192.168.10.137:554"))
@@ -131,13 +134,20 @@
}
isThirdConfirm = true
}
+
+ binding.endEnvCheckButton.setOnClickListener {
+ if (SocketManager.get.statusCode != ISocketListener.STATUS_CONNECT_SUCCESS) {
+ "指令发送失败,请确认是否处于同一网段".show(this)
+ return@setOnClickListener
+ }
+ SocketManager.get.send(LocaleConstant.END_ENV_COMMAND)
+ navigatePageTo()
+ }
}
override fun initOnCreate(savedInstanceState: Bundle?) {
ActivityStackManager.addActivity(this)
- startService(Intent(this, WebSocketMessageService::class.java))
-
weakReferenceHandler = WeakReferenceHandler(this)
constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java]
@@ -146,6 +156,8 @@
binding.videoView.start()
}
+ startWebSocket()
+
timer = Timer()
workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java]
timer.schedule(object : TimerTask() {
@@ -178,6 +190,45 @@
}
}
+ private fun startWebSocket() {
+ //初始化WebSocket
+ val httpClient = OkHttpClient.Builder()
+ .connectTimeout(10, TimeUnit.SECONDS)
+ .readTimeout(10, TimeUnit.SECONDS)
+ .writeTimeout(10, TimeUnit.SECONDS)
+ .build()
+ lifecycleScope.launch(Dispatchers.IO) {
+ val request = Request.Builder().url("ws://192.168.10.142:8765").build()
+ httpClient.newWebSocket(request, object : WebSocketListener() {
+ override fun onOpen(webSocket: WebSocket, response: Response) {
+ super.onOpen(webSocket, response)
+ this@EnvironmentActivity.webSocket = webSocket
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_CONNECTED_CODE)
+ }
+ }
+
+ override fun onMessage(webSocket: WebSocket, text: String) {
+ super.onMessage(webSocket, text)
+ lifecycleScope.launch(Dispatchers.Main) {
+ val message = weakReferenceHandler.obtainMessage()
+ message.what = LocaleConstant.WEBSOCKET_MESSAGE_CODE
+ message.obj = text
+ weakReferenceHandler.sendMessage(message)
+ }
+ }
+
+ override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
+ super.onFailure(webSocket, t, response)
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_DISCONNECTED_CODE)
+ }
+ }
+ })
+ httpClient.dispatcher.executorService.shutdown()
+ }
+ }
+
override fun initViewBinding(): ActivityEnvironmentBinding {
return ActivityEnvironmentBinding.inflate(layoutInflater)
}
@@ -203,5 +254,6 @@
super.onDestroy()
binding.videoView.suspend()
timer.cancel()
+ webSocket.close(1000, null)
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/operationsite/view/check/GuardiansActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/check/GuardiansActivity.kt
new file mode 100644
index 0000000..8805701
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/check/GuardiansActivity.kt
@@ -0,0 +1,270 @@
+package com.casic.br.operationsite.view.check
+
+import android.graphics.BitmapFactory
+import android.net.Uri
+import android.os.Bundle
+import android.os.Handler
+import android.os.Message
+import android.util.Base64
+import android.util.Log
+import android.view.View
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.lifecycleScope
+import com.casic.br.operationsite.R
+import com.casic.br.operationsite.databinding.ActivityGuardiansBinding
+import com.casic.br.operationsite.extensions.initImmersionBar
+import com.casic.br.operationsite.utils.LocaleConstant
+import com.casic.br.operationsite.utils.RuntimeCache
+import com.casic.br.operationsite.view.BigImageActivity
+import com.casic.br.operationsite.view.MainActivity
+import com.casic.br.operationsite.vm.AlarmViewModel
+import com.casic.br.operationsite.vm.ConstructionCheckViewModel
+import com.casic.br.operationsite.vm.WorkSiteViewModel
+import com.pengxh.kt.lite.adapter.EditableImageAdapter
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets
+import com.pengxh.kt.lite.extensions.createImageFileDir
+import com.pengxh.kt.lite.extensions.dp2px
+import com.pengxh.kt.lite.extensions.getScreenWidth
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.saveImage
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.extensions.toJson
+import com.pengxh.kt.lite.utils.ActivityStackManager
+import com.pengxh.kt.lite.utils.WeakReferenceHandler
+import com.pengxh.kt.lite.widget.TitleBarView
+import com.pengxh.kt.lite.widget.dialog.AlertControlDialog
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import okhttp3.Response
+import okhttp3.WebSocket
+import okhttp3.WebSocketListener
+import java.text.SimpleDateFormat
+import java.util.Date
+import java.util.Locale
+import java.util.Timer
+import java.util.TimerTask
+import java.util.concurrent.TimeUnit
+
+class GuardiansActivity : KotlinBaseActivity(), Handler.Callback {
+
+ private val kTag = "GuardiansActivity"
+ private val context = this
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
+ private lateinit var alarmViewModel: AlarmViewModel
+ private lateinit var constructionCheckViewModel: ConstructionCheckViewModel
+ private lateinit var workSiteViewModel: WorkSiteViewModel
+ private lateinit var imageAdapter: EditableImageAdapter
+ private lateinit var webSocket: WebSocket
+ private lateinit var timer: Timer
+ private val timeFormat by lazy { SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA) }
+ private val marginOffset by lazy { 1.dp2px(this) }
+ private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径
+
+ override fun initEvent() {
+ binding.alarmCheckbox.setOnCheckedChangeListener { _, isChecked ->
+ val state = if (isChecked) {
+ "1"
+ } else {
+ "0"
+ }
+ alarmViewModel.changeAlarmState("", state)
+ }
+
+ binding.setVideoRegionButton.setOnClickListener {
+ val region = binding.regionView.getConfirmedPoints()
+ Log.d(kTag, region.toJson())
+
+ constructionCheckViewModel.setVideoRegion(this, region)
+ }
+
+ binding.startVideoCheckButton.setOnClickListener {
+ constructionCheckViewModel.setCurrentPhase(this, "in_operation")
+ }
+
+ imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener {
+ override fun onAddImageClick() {
+ "当前模式不支持手动添加图片".show(context)
+ }
+
+ override fun onItemClick(position: Int) {
+ if (recyclerViewImages[position].isEmpty()) {
+ "图片加载失败,无法查看大图".show(context)
+ } else {
+ navigatePageTo(position, recyclerViewImages)
+ }
+ }
+
+ override fun onItemLongClick(view: View?, position: Int) {
+ recyclerViewImages.removeAt(position)
+ imageAdapter.notifyDataSetChanged()
+ }
+ })
+
+ binding.endTaskButton.setOnClickListener {
+ AlertControlDialog.Builder().setContext(this).setTitle("温馨提示")
+ .setMessage("确定结束此次施工?").setNegativeButton("取消").setPositiveButton("确定")
+ .setOnDialogButtonClickListener(object :
+ AlertControlDialog.OnDialogButtonClickListener {
+ override fun onConfirmClick() {
+ ActivityStackManager.finishActivity(DisclosureActivity::class.java)
+ ActivityStackManager.finishActivity(EnvironmentActivity::class.java)
+ ActivityStackManager.finishActivity(SuppliesActivity::class.java)
+ navigatePageTo()
+ finish()
+ }
+
+ override fun onCancelClick() {}
+ }).build().show()
+ }
+ }
+
+ override fun initOnCreate(savedInstanceState: Bundle?) {
+ ActivityStackManager.addActivity(this)
+
+ weakReferenceHandler = WeakReferenceHandler(this)
+ //播放RTSP流
+ binding.videoView.setVideoURI(Uri.parse("rtsp://192.168.10.137:554"))
+ binding.videoView.setOnPreparedListener {
+ binding.videoView.requestFocus()
+ binding.videoView.start()
+ }
+ startWebSocket()
+
+ alarmViewModel = ViewModelProvider(this)[AlarmViewModel::class.java]
+ alarmViewModel.alarmState.observe(this) {
+
+ }
+
+ constructionCheckViewModel = ViewModelProvider(this)[ConstructionCheckViewModel::class.java]
+ constructionCheckViewModel.postResult.observe(this) {
+ if (it.code == 200) {
+ "区域配置成功".show(this)
+ }
+ }
+
+ //左右边距
+ val viewWidth = getScreenWidth() - (15 + 15).dp2px(this)
+ imageAdapter = EditableImageAdapter(this, recyclerViewImages, viewWidth, 3, 3)
+ binding.recyclerView.addItemDecoration(
+ RecyclerViewItemOffsets(marginOffset, marginOffset, marginOffset, marginOffset)
+ )
+ binding.recyclerView.adapter = imageAdapter
+
+ timer = Timer()
+ workSiteViewModel = ViewModelProvider(this)[WorkSiteViewModel::class.java]
+ timer.schedule(object : TimerTask() {
+ override fun run() {
+ workSiteViewModel.getWorkers(context, RuntimeCache.projectId)
+ }
+ }, 0, 5000)
+ workSiteViewModel.workerResult.observe(this) {
+ if (it.code == 200) {
+ it.data.forEach { worker ->
+ if (worker.lat.isNotBlank() && worker.lng.isNotBlank()) {
+ val value =
+ "CO:${worker.co}ppm, CH4:${worker.gas}ppm, H2S:${worker.co}ppm, O2:${worker.o2}%VOL"
+ Log.d(kTag, "value: $value")
+ }
+ }
+ }
+ }
+ }
+
+ override fun handleMessage(msg: Message): Boolean {
+ when (msg.what) {
+ LocaleConstant.WEBSOCKET_CONNECTED_CODE -> "AI连接成功".show(this)
+
+ LocaleConstant.WEBSOCKET_MESSAGE_CODE -> {
+ try {
+ val bitmapArray = Base64.decode((msg.obj as String), Base64.DEFAULT)
+ val bitmap = BitmapFactory.decodeByteArray(bitmapArray, 0, bitmapArray.size)
+ val imagePath = "/${createImageFileDir()}/IMG${timeFormat.format(Date())}.png"
+ Log.d(kTag, "imagePath: $imagePath")
+ bitmap.saveImage(imagePath)
+ if (recyclerViewImages.size == 3) {
+ recyclerViewImages.removeAt(0)
+ }
+ recyclerViewImages.add(imagePath)
+ imageAdapter.notifyDataSetChanged()
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ LocaleConstant.WEBSOCKET_DISCONNECTED_CODE -> "AI连接失败".show(this)
+ }
+ return true
+ }
+
+ private fun startWebSocket() {
+ //初始化WebSocket
+ val httpClient = OkHttpClient.Builder().connectTimeout(10, TimeUnit.SECONDS)
+ .readTimeout(10, TimeUnit.SECONDS).writeTimeout(10, TimeUnit.SECONDS).build()
+ lifecycleScope.launch(Dispatchers.IO) {
+ val request = Request.Builder().url("ws://192.168.10.142:8765").build()
+ httpClient.newWebSocket(request, object : WebSocketListener() {
+ override fun onOpen(webSocket: WebSocket, response: Response) {
+ super.onOpen(webSocket, response)
+ this@GuardiansActivity.webSocket = webSocket
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_CONNECTED_CODE)
+ }
+ }
+
+ override fun onMessage(webSocket: WebSocket, text: String) {
+ super.onMessage(webSocket, text)
+ lifecycleScope.launch(Dispatchers.Main) {
+ val message = weakReferenceHandler.obtainMessage()
+ message.what = LocaleConstant.WEBSOCKET_MESSAGE_CODE
+ message.obj = text
+ weakReferenceHandler.sendMessage(message)
+ }
+ }
+
+ override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
+ super.onFailure(webSocket, t, response)
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_DISCONNECTED_CODE)
+ }
+ }
+ })
+ httpClient.dispatcher.executorService.shutdown()
+ }
+ }
+
+ override fun initViewBinding(): ActivityGuardiansBinding {
+ return ActivityGuardiansBinding.inflate(layoutInflater)
+ }
+
+ override fun observeRequestState() {
+
+ }
+
+ override fun setupTopBarLayout() {
+ binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor)
+ binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener {
+ override fun onLeftClick() {
+ finish()
+ }
+
+ override fun onRightClick() {
+
+ }
+ })
+ }
+
+ override fun onResume() {
+ super.onResume()
+ alarmViewModel.getAlarmState(this)
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ binding.videoView.suspend()
+ timer.cancel()
+ webSocket.close(1000, null)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/casic/br/operationsite/view/check/SuppliesActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/check/SuppliesActivity.kt
new file mode 100644
index 0000000..ba387fc
--- /dev/null
+++ b/app/src/main/java/com/casic/br/operationsite/view/check/SuppliesActivity.kt
@@ -0,0 +1,233 @@
+package com.casic.br.operationsite.view.check
+
+import android.content.Intent
+import android.graphics.BitmapFactory
+import android.net.Uri
+import android.os.Bundle
+import android.os.Handler
+import android.os.Message
+import android.util.Base64
+import android.util.Log
+import android.view.View
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.lifecycleScope
+import com.casic.br.operationsite.R
+import com.casic.br.operationsite.databinding.ActivitySuppliesBinding
+import com.casic.br.operationsite.extensions.initImmersionBar
+import com.casic.br.operationsite.utils.LocaleConstant
+import com.casic.br.operationsite.utils.tcp.ISocketListener
+import com.casic.br.operationsite.utils.tcp.SocketManager
+import com.casic.br.operationsite.view.BigImageActivity
+import com.casic.br.operationsite.view.HelmetVideoActivity
+import com.casic.br.operationsite.vm.ConstructionCheckViewModel
+import com.pengxh.kt.lite.adapter.EditableImageAdapter
+import com.pengxh.kt.lite.base.KotlinBaseActivity
+import com.pengxh.kt.lite.divider.RecyclerViewItemOffsets
+import com.pengxh.kt.lite.extensions.createImageFileDir
+import com.pengxh.kt.lite.extensions.dp2px
+import com.pengxh.kt.lite.extensions.getScreenWidth
+import com.pengxh.kt.lite.extensions.navigatePageTo
+import com.pengxh.kt.lite.extensions.saveImage
+import com.pengxh.kt.lite.extensions.show
+import com.pengxh.kt.lite.utils.ActivityStackManager
+import com.pengxh.kt.lite.utils.WeakReferenceHandler
+import com.pengxh.kt.lite.widget.TitleBarView
+import com.pengxh.kt.lite.widget.dialog.AlertControlDialog
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.launch
+import okhttp3.OkHttpClient
+import okhttp3.Request
+import okhttp3.Response
+import okhttp3.WebSocket
+import okhttp3.WebSocketListener
+import java.text.SimpleDateFormat
+import java.util.Date
+import java.util.Locale
+import java.util.concurrent.TimeUnit
+
+class SuppliesActivity : KotlinBaseActivity(), Handler.Callback {
+
+ private val kTag = "SuppliesActivity"
+ private val context = this
+ private lateinit var weakReferenceHandler: WeakReferenceHandler
+ private lateinit var constructionCheckViewModel: ConstructionCheckViewModel
+ private lateinit var imageAdapter: EditableImageAdapter
+ private lateinit var webSocket: WebSocket
+ private val timeFormat by lazy { SimpleDateFormat("yyyyMMddHHmmss", Locale.CHINA) }
+ private val marginOffset by lazy { 1.dp2px(this) }
+ private val recyclerViewImages: ArrayList = ArrayList() //真实图片路径
+
+ override fun initEvent() {
+ binding.startSuppliesCheckButton.setOnClickListener {
+ if (SocketManager.get.statusCode != ISocketListener.STATUS_CONNECT_SUCCESS) {
+ "指令发送失败,请确认是否处于同一网段".show(this)
+ return@setOnClickListener
+ }
+ SocketManager.get.send(LocaleConstant.START_SUPPLIES_COMMAND)
+ }
+
+ binding.startVideoCheckButton.setOnClickListener {
+ startVideoLauncher.launch(Intent(this, HelmetVideoActivity::class.java))
+ }
+
+ imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener {
+ override fun onAddImageClick() {
+ "当前模式不支持手动添加图片".show(context)
+ }
+
+ override fun onItemClick(position: Int) {
+ if (recyclerViewImages[position].isEmpty()) {
+ "图片加载失败,无法查看大图".show(context)
+ } else {
+ navigatePageTo(position, recyclerViewImages)
+ }
+ }
+
+ override fun onItemLongClick(view: View?, position: Int) {
+ recyclerViewImages.removeAt(position)
+ imageAdapter.notifyDataSetChanged()
+ }
+ })
+ }
+
+ private val startVideoLauncher = registerForActivityResult(
+ ActivityResultContracts.StartActivityForResult()
+ ) {
+ Log.d(kTag, "startVideoLauncher: ")
+ SocketManager.get.send(LocaleConstant.START_VIDEO_COMMAND)
+ constructionCheckViewModel.setCurrentPhase(this, "before_operation_protection")
+ //播放RTSP流
+ binding.videoView.setVideoURI(Uri.parse("rtsp://192.168.10.137:554"))
+ }
+
+ private fun startWebSocket() {
+ //初始化WebSocket
+ val httpClient = OkHttpClient.Builder()
+ .connectTimeout(10, TimeUnit.SECONDS)
+ .readTimeout(10, TimeUnit.SECONDS)
+ .writeTimeout(10, TimeUnit.SECONDS)
+ .build()
+ lifecycleScope.launch(Dispatchers.IO) {
+ val request = Request.Builder().url("ws://192.168.10.142:8765").build()
+ httpClient.newWebSocket(request, object : WebSocketListener() {
+ override fun onOpen(webSocket: WebSocket, response: Response) {
+ super.onOpen(webSocket, response)
+ this@SuppliesActivity.webSocket = webSocket
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_CONNECTED_CODE)
+ }
+ }
+
+ override fun onMessage(webSocket: WebSocket, text: String) {
+ super.onMessage(webSocket, text)
+ lifecycleScope.launch(Dispatchers.Main) {
+ val message = weakReferenceHandler.obtainMessage()
+ message.what = LocaleConstant.WEBSOCKET_MESSAGE_CODE
+ message.obj = text
+ weakReferenceHandler.sendMessage(message)
+ }
+ }
+
+ override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
+ super.onFailure(webSocket, t, response)
+ lifecycleScope.launch(Dispatchers.Main) {
+ weakReferenceHandler.sendEmptyMessage(LocaleConstant.WEBSOCKET_DISCONNECTED_CODE)
+ }
+ }
+ })
+ httpClient.dispatcher.executorService.shutdown()
+ }
+ }
+
+ override fun initOnCreate(savedInstanceState: Bundle?) {
+ ActivityStackManager.addActivity(this)
+
+ weakReferenceHandler = WeakReferenceHandler(this)
+ constructionCheckViewModel =
+ ViewModelProvider(this)[ConstructionCheckViewModel::class.java]
+
+ startWebSocket()
+
+ binding.videoView.setOnPreparedListener {
+ binding.videoView.requestFocus()
+ binding.videoView.start()
+ }
+
+ //左右边距
+ val viewWidth = getScreenWidth() - (15 + 15).dp2px(this)
+ imageAdapter = EditableImageAdapter(this, recyclerViewImages, viewWidth, 6, 3)
+ binding.recyclerView.addItemDecoration(
+ RecyclerViewItemOffsets(marginOffset, marginOffset, marginOffset, marginOffset)
+ )
+ binding.recyclerView.adapter = imageAdapter
+ }
+
+ override fun handleMessage(msg: Message): Boolean {
+ when (msg.what) {
+ LocaleConstant.WEBSOCKET_CONNECTED_CODE -> "AI连接成功".show(this)
+
+ LocaleConstant.WEBSOCKET_MESSAGE_CODE -> {
+ try {
+ val bitmapArray = Base64.decode((msg.obj as String), Base64.DEFAULT)
+ val bitmap = BitmapFactory.decodeByteArray(bitmapArray, 0, bitmapArray.size)
+ val imagePath =
+ "/${createImageFileDir()}/IMG${timeFormat.format(Date())}.png"
+ Log.d(kTag, "imagePath: $imagePath")
+ bitmap.saveImage(imagePath)
+ recyclerViewImages.add(imagePath)
+ imageAdapter.notifyDataSetChanged()
+
+ if (recyclerViewImages.size == 6) {
+ AlertControlDialog.Builder()
+ .setContext(this)
+ .setTitle("温馨提示")
+ .setMessage("检测到施工前劳保用品准备完毕,是否开始施工?")
+ .setNegativeButton("取消")
+ .setPositiveButton("确定")
+ .setOnDialogButtonClickListener(object :
+ AlertControlDialog.OnDialogButtonClickListener {
+ override fun onConfirmClick() {
+ navigatePageTo()
+ }
+
+ override fun onCancelClick() {}
+ }).build().show()
+ }
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ }
+
+ LocaleConstant.WEBSOCKET_DISCONNECTED_CODE -> "AI连接失败".show(this)
+ }
+ return true
+ }
+
+ override fun initViewBinding(): ActivitySuppliesBinding {
+ return ActivitySuppliesBinding.inflate(layoutInflater)
+ }
+
+ override fun observeRequestState() {
+
+ }
+
+ override fun setupTopBarLayout() {
+ binding.rootView.initImmersionBar(this, false, R.color.mainThemeColor)
+ binding.titleView.setOnClickListener(object : TitleBarView.OnClickListener {
+ override fun onLeftClick() {
+ finish()
+ }
+
+ override fun onRightClick() {
+
+ }
+ })
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ binding.videoView.suspend()
+ webSocket.close(1000, null)
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_guardians.xml b/app/src/main/res/layout/activity_guardians.xml
new file mode 100644
index 0000000..5403809
--- /dev/null
+++ b/app/src/main/res/layout/activity_guardians.xml
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_site_tab.xml b/app/src/main/res/layout/activity_site_tab.xml
index 079220e..8053288 100644
--- a/app/src/main/res/layout/activity_site_tab.xml
+++ b/app/src/main/res/layout/activity_site_tab.xml
@@ -134,13 +134,6 @@
android:text="所属道路:"
android:textSize="@dimen/sp_14" />
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file