diff --git "a/app/src/main/assets/SearchMarkerActivity - \346\274\224\347\244\272\347\211\210\344\273\243\347\240\201\345\244\207\344\273\275.kt" "b/app/src/main/assets/SearchMarkerActivity - \346\274\224\347\244\272\347\211\210\344\273\243\347\240\201\345\244\207\344\273\275.kt" new file mode 100644 index 0000000..b3e68e3 --- /dev/null +++ "b/app/src/main/assets/SearchMarkerActivity - \346\274\224\347\244\272\347\211\210\344\273\243\347\240\201\345\244\207\344\273\275.kt" @@ -0,0 +1,447 @@ +import android.content.res.ColorStateList +import android.graphics.Color +import android.hardware.Sensor +import android.hardware.SensorEvent +import android.hardware.SensorEventListener +import android.hardware.SensorManager +import android.media.AudioAttributes +import android.media.SoundPool +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.view.View +import androidx.core.graphics.toColorInt +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.lifecycleScope +import com.amap.api.location.AMapLocation +import com.amap.api.maps.AMapUtils +import com.amap.api.maps.model.LatLng +import com.casic.common.detector.gd.R +import com.casic.common.detector.gd.base.BaseApplication +import com.casic.common.detector.gd.base.SerialPortBaseActivity +import com.casic.common.detector.gd.callback.OnGetLocationListener +import com.casic.common.detector.gd.databinding.ActivitySearchMarkerBinding +import com.casic.common.detector.gd.model.MarkerDistanceData +import com.casic.common.detector.gd.utils.CurrentSegment +import com.casic.common.detector.gd.utils.LocaleConstant +import com.casic.common.detector.gd.utils.LocationKit +import com.casic.common.detector.gd.utils.RuntimeCache +import com.casic.common.detector.gd.utils.SerialPortCommand +import com.casic.common.detector.gd.vm.TaskViewModel +import com.casic.common.detector.gd.widgets.MarkerDetailDialog +import com.casic.common.detector.gd.widgets.NewMarkerDetailDialog +import com.casic.common.detector.gd.widgets.RadarScanView +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.LiteKitConstant +import com.pengxh.kt.lite.utils.LoadingDialog +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.widget.dialog.AlertMessageDialog +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import kotlin.math.atan2 + +class SearchMarkerActivity : SerialPortBaseActivity(), + SensorEventListener { + + private val kTag = "SearchMarkerActivity" + private val context = this + private val locationKit by lazy { LocationKit(this) } + private val markerPoints by lazy { ArrayList() } + private val markerBeanDao by lazy { BaseApplication.get().dataBase.markerBeanDao() } + private val taskMarkerBeanDao by lazy { BaseApplication.get().dataBase.taskMarkerBeanDao() } + private val taskViewModel by lazy { ViewModelProvider(this)[TaskViewModel::class.java] } + private val sensorManager by lazy { getSystemService(SENSOR_SERVICE) as SensorManager } + private val attr = AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_ALARM) + .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build() + private val soundPool = SoundPool.Builder().setMaxStreams(16).setAudioAttributes(attr).build() + private val rotationMatrix = FloatArray(9)//旋转矩阵缓存 + private val valueArray = FloatArray(3)//方位角数值 + private var slowSoundResourceId = 0 + private var fastSoundResourceId = 0 + private var databaseMarkerId = ""//本地数据库标识器ID + private var detectedMarkerId = ""//真实探测到标识器ID + private var isExecuteTask = false + private var gravity: FloatArray? = null + private var geomagnetic: FloatArray? = null + + override fun initOnCreate(savedInstanceState: Bundle?) { + RuntimeCache.currentSegment = CurrentSegment.SearchMarker + val taskState = intent.getStringExtra(LiteKitConstant.INTENT_PARAM_KEY) as String + isExecuteTask = taskState != "0" + + slowSoundResourceId = soundPool.load(this, R.raw.ring4, 1) + fastSoundResourceId = soundPool.load(this, R.raw.ring2, 1) + + //点位渲染,每次定位都计算当前位置与符合条件的点距离 + locationKit.getCurrentLocation(false, object : OnGetLocationListener { + override fun onSuccess(location: AMapLocation) { + renderDataPoint(location) + } + + override fun onError() { + "当前位置信号差,无法获取定位".show(context) + } + }) + + if (isExecuteTask) { + binding.taskStateView.visibility = View.GONE + binding.taskStateView.isSelected = false + } else { + binding.taskStateView.visibility = View.VISIBLE + binding.taskStateView.isSelected = true + } + + //进入界面开始搜索信号强度 + sendSerialPortCommand(SerialPortCommand.SEARCH_SIGNAL) + } + + private val handler = Handler(Looper.getMainLooper()) + private var detectDepthRunnable: DetectDepthRunnable? = null + + private inner class DetectDepthRunnable(private val command: Int) : Runnable { + override fun run() { + sendSerialPortCommand(command) + //延迟三秒再发一次 + handler.postDelayed(this, 3000) + } + } + + override fun initEvent() { + binding.depthButton.setOnClickListener { + if (detectedMarkerId == "") { + //还没探测到,直接显示当初埋深 + val result = markerBeanDao.queryMarkerById(databaseMarkerId) + val depth = if (result.isNotEmpty()) { + "110厘米" + } else { + result.first().markerDepth + } + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("温馨提示") + .setMessage("标识器埋深:$depth") + .setPositiveButton("知道了") + .setOnDialogButtonClickListener(object : + AlertMessageDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + RuntimeCache.currentSegment = CurrentSegment.SearchMarker + sendSerialPortCommand(SerialPortCommand.SEARCH_SIGNAL) + } + }).build().show() + return@setOnClickListener + } + + //真实探测埋深 + RuntimeCache.currentSegment = CurrentSegment.DetectDepth + val result = markerBeanDao.queryMarkerById(detectedMarkerId) + if (result.isNotEmpty()) { + val command = when (result.first().markerType) { + "EM30" -> SerialPortCommand.DETECT_EM30_DEPTH + "EM50" -> SerialPortCommand.DETECT_EM50_DEPTH + "EM14" -> SerialPortCommand.DETECT_EM14_DEPTH + else -> SerialPortCommand.STOP_SERIAL_PORT_DATA + } + if (command == SerialPortCommand.STOP_SERIAL_PORT_DATA) { + "此标识器无法读取埋深!".show(this) + } else { + soundPool.autoPause() + LoadingDialog.show(this, "正在探测标识器埋深,请稍后...") + + // 移除之前的 Runnable(如果存在) + detectDepthRunnable?.let { handler.removeCallbacks(it) } + detectDepthRunnable = DetectDepthRunnable(command) + // 发送读取标识器埋设深度指令 + handler.post(detectDepthRunnable!!) + } + } else { + "标识器未安装,安装成功后才可读取埋深!".show(this) + } + } + + binding.markerIdButton.setOnClickListener { + sendSerialPortCommand(SerialPortCommand.SEARCH_MARKER_ALWAYS) + } + + binding.markerInfoButton.setOnClickListener { + val markerId = if (detectedMarkerId == "") { + databaseMarkerId + } else { + detectedMarkerId + } + val result = markerBeanDao.queryMarkerById(markerId) + if (result.isNotEmpty()) { + MarkerDetailDialog(this).setMarker(result.first()).show() + } else { + NewMarkerDetailDialog(this, markerId) + } + //查询完之后重置ID,以便下次重走逻辑 + databaseMarkerId = "" + detectedMarkerId = "" + } + } + + override fun onMarkerIdDetected(markerId: String) { + if (RuntimeCache.currentSegment == CurrentSegment.SearchMarker) { + binding.depthButton.isEnabled = true + binding.depthButton.setTextColor(Color.WHITE) + binding.depthButton.backgroundTintList = + ColorStateList.valueOf("#004364".toColorInt()) + + binding.markerInfoButton.isEnabled = true + binding.markerInfoButton.setTextColor(Color.WHITE) + binding.markerInfoButton.backgroundTintList = + ColorStateList.valueOf("#FFA200".toColorInt()) + + handleMarker(markerId) + } + } + + private fun handleMarker(id: String) { + detectedMarkerId = id + //自动上传标识器 + if (isExecuteTask) { + val taskId = SaveKeyValues.getValue(LocaleConstant.TASK_ID, "") as String + val taskCode = SaveKeyValues.getValue(LocaleConstant.TASK_CODE, "") as String + val marker = taskMarkerBeanDao.queryTaskMarkerById( + taskId, taskCode, id, "0" + ) + if (marker == null) { + return + } + taskViewModel.uploadMarker( + marker.markerId, + onLoading = {}, + onSuccess = { + "标识器${marker.markerId}已探测!".show(this) + marker.isDetected = "1" + taskMarkerBeanDao.updateLocalTaskMarkerState(marker) + }, + onFailed = {} + ) + } + } + + override fun onMarkerDepthDetected(depth: Int) { + if (RuntimeCache.currentSegment == CurrentSegment.DetectDepth) { + detectDepthRunnable?.let { handler.removeCallbacks(it) } + detectDepthRunnable = null + LoadingDialog.dismiss() + if (!this.isDestroyed) { + AlertMessageDialog.Builder() + .setContext(context) + .setTitle("温馨提示") + .setMessage("标识器埋深:${depth}厘米") + .setPositiveButton("知道了") + .setOnDialogButtonClickListener(object : + AlertMessageDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + RuntimeCache.currentSegment = CurrentSegment.SearchMarker + sendSerialPortCommand(SerialPortCommand.SEARCH_SIGNAL) + } + }).build().show() + } else { + "标识器埋深:${depth}厘米".show(this) + } + } + } + + override fun onMarkerSignalDetected(signalEnergy: Int) { + if (RuntimeCache.currentSegment == CurrentSegment.SearchMarker) { + if (signalEnergy > 1000) { + binding.markerIdButton.isEnabled = true + binding.markerIdButton.setTextColor("#428d00".toColorInt()) + binding.markerIdButton.backgroundTintList = ColorStateList.valueOf( + "#7EFF00".toColorInt() + ) + + binding.searchResultView.text = "已检测到标识器" + binding.searchResultView.setTextColor("#428d00".toColorInt()) + binding.searchResultView.setBackgroundResource(R.mipmap.bg_small_text_green) + } + + //声音 + val soundResourceId = if (signalEnergy >= 4000) + fastSoundResourceId else slowSoundResourceId + soundPool.play(soundResourceId, 1f, 1f, 0, 0, 1f) + + //信号强度显示 + binding.energyPgBar.progress = signalEnergy + binding.energyValueView.text = "${signalEnergy}dB" + + //搜索信号文字显示 + updateTextResult(signalEnergy) + } + } + + private fun updateTextResult(signalEnergy: Int) { + when { + signalEnergy <= 700 -> { + setEnergyTip( + "信号较弱,可能距离较远", + "#8D1717".toColorInt(), + R.mipmap.bg_large_text_red + ) +// disableButtons() + binding.searchResultView.text = "未检测到标识器" + binding.searchResultView.setTextColor("#8D1717".toColorInt()) + binding.searchResultView.setBackgroundResource(R.mipmap.bg_small_text_red) + } + + signalEnergy >= 4100 -> { + setEnergyTip( + "信号极强,接近标识器正上方", + "#428d00".toColorInt(), + R.mipmap.bg_large_text_green + ) + } + + else -> { + setEnergyTip( + "已靠近,请继续移动位置", + "#8C5700".toColorInt(), + R.mipmap.bg_large_text_yellow + ) + } + } + } + + private fun setEnergyTip(text: String, textColorRes: Int, backgroundRes: Int) { + binding.energyTipsView.text = text + binding.energyTipsView.setTextColor(textColorRes) + binding.energyTipsView.setBackgroundResource(backgroundRes) + } + + private val colorStateList = ColorStateList.valueOf("#8A8A8A".toColorInt()) + private val textColor = "#CCCCCC".toColorInt() + + private fun disableButtons() { + binding.depthButton.isEnabled = false + binding.depthButton.setTextColor(textColor) + binding.depthButton.backgroundTintList = colorStateList + binding.markerIdButton.isEnabled = false + binding.markerIdButton.setTextColor(textColor) + binding.markerIdButton.backgroundTintList = colorStateList + binding.markerInfoButton.isEnabled = false + binding.markerInfoButton.setTextColor(textColor) + binding.markerInfoButton.backgroundTintList = colorStateList + } + + /** + * 计算并渲染数据点。点太多采用协程计算,不然会有点卡顿。默认2s计算一次 + * @param location 定位点(RTK获取) + * */ + private fun renderDataPoint(location: AMapLocation) { + val longitude = location.longitude + val latitude = location.latitude + lifecycleScope.launch(Dispatchers.IO) { + val dataPoints = ArrayList() + markerBeanDao.loadAll().forEach { + val distance = AMapUtils.calculateLineDistance( + LatLng(it.lat.toDouble(), it.lng.toDouble()), LatLng(latitude, longitude) + ) + val formatDistance = "%.2f".format(distance).toFloat() + markerPoints.add(MarkerDistanceData(it.markerId, formatDistance)) + + if (formatDistance <= LocaleConstant.MAX_DISTANCE) { + val angle = atan2( + (it.lat.toDouble() - latitude), (it.lng.toDouble() - longitude) + ) + Math.PI + val formatAngle = "%.2f".format(angle).toDouble() + + dataPoints.add( + RadarScanView.DataPoint(it.markerId, formatAngle, formatDistance) + ) + } + } + withContext(Dispatchers.Main) { + binding.radarScanView.renderPointData( + dataPoints, + onGetNearestPoint = { point -> + if (point == null) { + binding.distanceValueView.text = "大于5.5m" + binding.distancePgBar.progress = 100 + } else { + databaseMarkerId = point.markerId + + binding.depthButton.isEnabled = true + binding.depthButton.setTextColor(Color.WHITE) + binding.depthButton.backgroundTintList = + ColorStateList.valueOf("#004364".toColorInt()) + + binding.markerInfoButton.isEnabled = true + binding.markerInfoButton.setTextColor(Color.WHITE) + binding.markerInfoButton.backgroundTintList = + ColorStateList.valueOf("#FFA200".toColorInt()) + + binding.distanceValueView.text = "${point.distance}m" + val progress = if (point.distance > LocaleConstant.MAX_DISTANCE) { + 100 + } else { + (point.distance / LocaleConstant.MAX_DISTANCE) * 100 + } + binding.distancePgBar.progress = progress.toInt() + } + } + ) + } + } + } + + override fun initViewBinding(): ActivitySearchMarkerBinding { + return ActivitySearchMarkerBinding.inflate(layoutInflater) + } + + override fun setupTopBarLayout() { + + } + + override fun onResume() { + super.onResume() + //注册加速度传感器监听 + val accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) + sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL) + + //注册磁场传感器监听 + val magnetic = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) + sensorManager.registerListener(this, magnetic, SensorManager.SENSOR_DELAY_NORMAL) + } + + override fun onPause() { + super.onPause() + sensorManager.unregisterListener(this) + } + + override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) { + //精度发生变化时触发 + } + + override fun onSensorChanged(event: SensorEvent?) { + //值发生变化时触发 + val type = event?.sensor?.type + + if (type == Sensor.TYPE_ACCELEROMETER) { + gravity = event.values + } else if (type == Sensor.TYPE_MAGNETIC_FIELD) { + geomagnetic = event.values + } + + if (gravity == null || geomagnetic == null) { + return + } + + if (SensorManager.getRotationMatrix(rotationMatrix, null, gravity, geomagnetic)) { + SensorManager.getOrientation(rotationMatrix, valueArray) + + val degree = ((360f + valueArray[0] * 180f / Math.PI) % 360).toInt() + //更新罗盘角度 + binding.radarScanView.setDegreeValue(degree) + } + } + + override fun onDestroy() { + super.onDestroy() + soundPool.autoPause() + locationKit.stopLocation() + } +} \ No newline at end of file diff --git "a/app/src/main/assets/SearchMarkerActivity - \346\274\224\347\244\272\347\211\210\344\273\243\347\240\201\345\244\207\344\273\275.kt" "b/app/src/main/assets/SearchMarkerActivity - \346\274\224\347\244\272\347\211\210\344\273\243\347\240\201\345\244\207\344\273\275.kt" new file mode 100644 index 0000000..b3e68e3 --- /dev/null +++ "b/app/src/main/assets/SearchMarkerActivity - \346\274\224\347\244\272\347\211\210\344\273\243\347\240\201\345\244\207\344\273\275.kt" @@ -0,0 +1,447 @@ +import android.content.res.ColorStateList +import android.graphics.Color +import android.hardware.Sensor +import android.hardware.SensorEvent +import android.hardware.SensorEventListener +import android.hardware.SensorManager +import android.media.AudioAttributes +import android.media.SoundPool +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.view.View +import androidx.core.graphics.toColorInt +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.lifecycleScope +import com.amap.api.location.AMapLocation +import com.amap.api.maps.AMapUtils +import com.amap.api.maps.model.LatLng +import com.casic.common.detector.gd.R +import com.casic.common.detector.gd.base.BaseApplication +import com.casic.common.detector.gd.base.SerialPortBaseActivity +import com.casic.common.detector.gd.callback.OnGetLocationListener +import com.casic.common.detector.gd.databinding.ActivitySearchMarkerBinding +import com.casic.common.detector.gd.model.MarkerDistanceData +import com.casic.common.detector.gd.utils.CurrentSegment +import com.casic.common.detector.gd.utils.LocaleConstant +import com.casic.common.detector.gd.utils.LocationKit +import com.casic.common.detector.gd.utils.RuntimeCache +import com.casic.common.detector.gd.utils.SerialPortCommand +import com.casic.common.detector.gd.vm.TaskViewModel +import com.casic.common.detector.gd.widgets.MarkerDetailDialog +import com.casic.common.detector.gd.widgets.NewMarkerDetailDialog +import com.casic.common.detector.gd.widgets.RadarScanView +import com.pengxh.kt.lite.extensions.show +import com.pengxh.kt.lite.utils.LiteKitConstant +import com.pengxh.kt.lite.utils.LoadingDialog +import com.pengxh.kt.lite.utils.SaveKeyValues +import com.pengxh.kt.lite.widget.dialog.AlertMessageDialog +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import kotlin.math.atan2 + +class SearchMarkerActivity : SerialPortBaseActivity(), + SensorEventListener { + + private val kTag = "SearchMarkerActivity" + private val context = this + private val locationKit by lazy { LocationKit(this) } + private val markerPoints by lazy { ArrayList() } + private val markerBeanDao by lazy { BaseApplication.get().dataBase.markerBeanDao() } + private val taskMarkerBeanDao by lazy { BaseApplication.get().dataBase.taskMarkerBeanDao() } + private val taskViewModel by lazy { ViewModelProvider(this)[TaskViewModel::class.java] } + private val sensorManager by lazy { getSystemService(SENSOR_SERVICE) as SensorManager } + private val attr = AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_ALARM) + .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC).build() + private val soundPool = SoundPool.Builder().setMaxStreams(16).setAudioAttributes(attr).build() + private val rotationMatrix = FloatArray(9)//旋转矩阵缓存 + private val valueArray = FloatArray(3)//方位角数值 + private var slowSoundResourceId = 0 + private var fastSoundResourceId = 0 + private var databaseMarkerId = ""//本地数据库标识器ID + private var detectedMarkerId = ""//真实探测到标识器ID + private var isExecuteTask = false + private var gravity: FloatArray? = null + private var geomagnetic: FloatArray? = null + + override fun initOnCreate(savedInstanceState: Bundle?) { + RuntimeCache.currentSegment = CurrentSegment.SearchMarker + val taskState = intent.getStringExtra(LiteKitConstant.INTENT_PARAM_KEY) as String + isExecuteTask = taskState != "0" + + slowSoundResourceId = soundPool.load(this, R.raw.ring4, 1) + fastSoundResourceId = soundPool.load(this, R.raw.ring2, 1) + + //点位渲染,每次定位都计算当前位置与符合条件的点距离 + locationKit.getCurrentLocation(false, object : OnGetLocationListener { + override fun onSuccess(location: AMapLocation) { + renderDataPoint(location) + } + + override fun onError() { + "当前位置信号差,无法获取定位".show(context) + } + }) + + if (isExecuteTask) { + binding.taskStateView.visibility = View.GONE + binding.taskStateView.isSelected = false + } else { + binding.taskStateView.visibility = View.VISIBLE + binding.taskStateView.isSelected = true + } + + //进入界面开始搜索信号强度 + sendSerialPortCommand(SerialPortCommand.SEARCH_SIGNAL) + } + + private val handler = Handler(Looper.getMainLooper()) + private var detectDepthRunnable: DetectDepthRunnable? = null + + private inner class DetectDepthRunnable(private val command: Int) : Runnable { + override fun run() { + sendSerialPortCommand(command) + //延迟三秒再发一次 + handler.postDelayed(this, 3000) + } + } + + override fun initEvent() { + binding.depthButton.setOnClickListener { + if (detectedMarkerId == "") { + //还没探测到,直接显示当初埋深 + val result = markerBeanDao.queryMarkerById(databaseMarkerId) + val depth = if (result.isNotEmpty()) { + "110厘米" + } else { + result.first().markerDepth + } + AlertMessageDialog.Builder() + .setContext(this) + .setTitle("温馨提示") + .setMessage("标识器埋深:$depth") + .setPositiveButton("知道了") + .setOnDialogButtonClickListener(object : + AlertMessageDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + RuntimeCache.currentSegment = CurrentSegment.SearchMarker + sendSerialPortCommand(SerialPortCommand.SEARCH_SIGNAL) + } + }).build().show() + return@setOnClickListener + } + + //真实探测埋深 + RuntimeCache.currentSegment = CurrentSegment.DetectDepth + val result = markerBeanDao.queryMarkerById(detectedMarkerId) + if (result.isNotEmpty()) { + val command = when (result.first().markerType) { + "EM30" -> SerialPortCommand.DETECT_EM30_DEPTH + "EM50" -> SerialPortCommand.DETECT_EM50_DEPTH + "EM14" -> SerialPortCommand.DETECT_EM14_DEPTH + else -> SerialPortCommand.STOP_SERIAL_PORT_DATA + } + if (command == SerialPortCommand.STOP_SERIAL_PORT_DATA) { + "此标识器无法读取埋深!".show(this) + } else { + soundPool.autoPause() + LoadingDialog.show(this, "正在探测标识器埋深,请稍后...") + + // 移除之前的 Runnable(如果存在) + detectDepthRunnable?.let { handler.removeCallbacks(it) } + detectDepthRunnable = DetectDepthRunnable(command) + // 发送读取标识器埋设深度指令 + handler.post(detectDepthRunnable!!) + } + } else { + "标识器未安装,安装成功后才可读取埋深!".show(this) + } + } + + binding.markerIdButton.setOnClickListener { + sendSerialPortCommand(SerialPortCommand.SEARCH_MARKER_ALWAYS) + } + + binding.markerInfoButton.setOnClickListener { + val markerId = if (detectedMarkerId == "") { + databaseMarkerId + } else { + detectedMarkerId + } + val result = markerBeanDao.queryMarkerById(markerId) + if (result.isNotEmpty()) { + MarkerDetailDialog(this).setMarker(result.first()).show() + } else { + NewMarkerDetailDialog(this, markerId) + } + //查询完之后重置ID,以便下次重走逻辑 + databaseMarkerId = "" + detectedMarkerId = "" + } + } + + override fun onMarkerIdDetected(markerId: String) { + if (RuntimeCache.currentSegment == CurrentSegment.SearchMarker) { + binding.depthButton.isEnabled = true + binding.depthButton.setTextColor(Color.WHITE) + binding.depthButton.backgroundTintList = + ColorStateList.valueOf("#004364".toColorInt()) + + binding.markerInfoButton.isEnabled = true + binding.markerInfoButton.setTextColor(Color.WHITE) + binding.markerInfoButton.backgroundTintList = + ColorStateList.valueOf("#FFA200".toColorInt()) + + handleMarker(markerId) + } + } + + private fun handleMarker(id: String) { + detectedMarkerId = id + //自动上传标识器 + if (isExecuteTask) { + val taskId = SaveKeyValues.getValue(LocaleConstant.TASK_ID, "") as String + val taskCode = SaveKeyValues.getValue(LocaleConstant.TASK_CODE, "") as String + val marker = taskMarkerBeanDao.queryTaskMarkerById( + taskId, taskCode, id, "0" + ) + if (marker == null) { + return + } + taskViewModel.uploadMarker( + marker.markerId, + onLoading = {}, + onSuccess = { + "标识器${marker.markerId}已探测!".show(this) + marker.isDetected = "1" + taskMarkerBeanDao.updateLocalTaskMarkerState(marker) + }, + onFailed = {} + ) + } + } + + override fun onMarkerDepthDetected(depth: Int) { + if (RuntimeCache.currentSegment == CurrentSegment.DetectDepth) { + detectDepthRunnable?.let { handler.removeCallbacks(it) } + detectDepthRunnable = null + LoadingDialog.dismiss() + if (!this.isDestroyed) { + AlertMessageDialog.Builder() + .setContext(context) + .setTitle("温馨提示") + .setMessage("标识器埋深:${depth}厘米") + .setPositiveButton("知道了") + .setOnDialogButtonClickListener(object : + AlertMessageDialog.OnDialogButtonClickListener { + override fun onConfirmClick() { + RuntimeCache.currentSegment = CurrentSegment.SearchMarker + sendSerialPortCommand(SerialPortCommand.SEARCH_SIGNAL) + } + }).build().show() + } else { + "标识器埋深:${depth}厘米".show(this) + } + } + } + + override fun onMarkerSignalDetected(signalEnergy: Int) { + if (RuntimeCache.currentSegment == CurrentSegment.SearchMarker) { + if (signalEnergy > 1000) { + binding.markerIdButton.isEnabled = true + binding.markerIdButton.setTextColor("#428d00".toColorInt()) + binding.markerIdButton.backgroundTintList = ColorStateList.valueOf( + "#7EFF00".toColorInt() + ) + + binding.searchResultView.text = "已检测到标识器" + binding.searchResultView.setTextColor("#428d00".toColorInt()) + binding.searchResultView.setBackgroundResource(R.mipmap.bg_small_text_green) + } + + //声音 + val soundResourceId = if (signalEnergy >= 4000) + fastSoundResourceId else slowSoundResourceId + soundPool.play(soundResourceId, 1f, 1f, 0, 0, 1f) + + //信号强度显示 + binding.energyPgBar.progress = signalEnergy + binding.energyValueView.text = "${signalEnergy}dB" + + //搜索信号文字显示 + updateTextResult(signalEnergy) + } + } + + private fun updateTextResult(signalEnergy: Int) { + when { + signalEnergy <= 700 -> { + setEnergyTip( + "信号较弱,可能距离较远", + "#8D1717".toColorInt(), + R.mipmap.bg_large_text_red + ) +// disableButtons() + binding.searchResultView.text = "未检测到标识器" + binding.searchResultView.setTextColor("#8D1717".toColorInt()) + binding.searchResultView.setBackgroundResource(R.mipmap.bg_small_text_red) + } + + signalEnergy >= 4100 -> { + setEnergyTip( + "信号极强,接近标识器正上方", + "#428d00".toColorInt(), + R.mipmap.bg_large_text_green + ) + } + + else -> { + setEnergyTip( + "已靠近,请继续移动位置", + "#8C5700".toColorInt(), + R.mipmap.bg_large_text_yellow + ) + } + } + } + + private fun setEnergyTip(text: String, textColorRes: Int, backgroundRes: Int) { + binding.energyTipsView.text = text + binding.energyTipsView.setTextColor(textColorRes) + binding.energyTipsView.setBackgroundResource(backgroundRes) + } + + private val colorStateList = ColorStateList.valueOf("#8A8A8A".toColorInt()) + private val textColor = "#CCCCCC".toColorInt() + + private fun disableButtons() { + binding.depthButton.isEnabled = false + binding.depthButton.setTextColor(textColor) + binding.depthButton.backgroundTintList = colorStateList + binding.markerIdButton.isEnabled = false + binding.markerIdButton.setTextColor(textColor) + binding.markerIdButton.backgroundTintList = colorStateList + binding.markerInfoButton.isEnabled = false + binding.markerInfoButton.setTextColor(textColor) + binding.markerInfoButton.backgroundTintList = colorStateList + } + + /** + * 计算并渲染数据点。点太多采用协程计算,不然会有点卡顿。默认2s计算一次 + * @param location 定位点(RTK获取) + * */ + private fun renderDataPoint(location: AMapLocation) { + val longitude = location.longitude + val latitude = location.latitude + lifecycleScope.launch(Dispatchers.IO) { + val dataPoints = ArrayList() + markerBeanDao.loadAll().forEach { + val distance = AMapUtils.calculateLineDistance( + LatLng(it.lat.toDouble(), it.lng.toDouble()), LatLng(latitude, longitude) + ) + val formatDistance = "%.2f".format(distance).toFloat() + markerPoints.add(MarkerDistanceData(it.markerId, formatDistance)) + + if (formatDistance <= LocaleConstant.MAX_DISTANCE) { + val angle = atan2( + (it.lat.toDouble() - latitude), (it.lng.toDouble() - longitude) + ) + Math.PI + val formatAngle = "%.2f".format(angle).toDouble() + + dataPoints.add( + RadarScanView.DataPoint(it.markerId, formatAngle, formatDistance) + ) + } + } + withContext(Dispatchers.Main) { + binding.radarScanView.renderPointData( + dataPoints, + onGetNearestPoint = { point -> + if (point == null) { + binding.distanceValueView.text = "大于5.5m" + binding.distancePgBar.progress = 100 + } else { + databaseMarkerId = point.markerId + + binding.depthButton.isEnabled = true + binding.depthButton.setTextColor(Color.WHITE) + binding.depthButton.backgroundTintList = + ColorStateList.valueOf("#004364".toColorInt()) + + binding.markerInfoButton.isEnabled = true + binding.markerInfoButton.setTextColor(Color.WHITE) + binding.markerInfoButton.backgroundTintList = + ColorStateList.valueOf("#FFA200".toColorInt()) + + binding.distanceValueView.text = "${point.distance}m" + val progress = if (point.distance > LocaleConstant.MAX_DISTANCE) { + 100 + } else { + (point.distance / LocaleConstant.MAX_DISTANCE) * 100 + } + binding.distancePgBar.progress = progress.toInt() + } + } + ) + } + } + } + + override fun initViewBinding(): ActivitySearchMarkerBinding { + return ActivitySearchMarkerBinding.inflate(layoutInflater) + } + + override fun setupTopBarLayout() { + + } + + override fun onResume() { + super.onResume() + //注册加速度传感器监听 + val accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) + sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL) + + //注册磁场传感器监听 + val magnetic = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) + sensorManager.registerListener(this, magnetic, SensorManager.SENSOR_DELAY_NORMAL) + } + + override fun onPause() { + super.onPause() + sensorManager.unregisterListener(this) + } + + override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) { + //精度发生变化时触发 + } + + override fun onSensorChanged(event: SensorEvent?) { + //值发生变化时触发 + val type = event?.sensor?.type + + if (type == Sensor.TYPE_ACCELEROMETER) { + gravity = event.values + } else if (type == Sensor.TYPE_MAGNETIC_FIELD) { + geomagnetic = event.values + } + + if (gravity == null || geomagnetic == null) { + return + } + + if (SensorManager.getRotationMatrix(rotationMatrix, null, gravity, geomagnetic)) { + SensorManager.getOrientation(rotationMatrix, valueArray) + + val degree = ((360f + valueArray[0] * 180f / Math.PI) % 360).toInt() + //更新罗盘角度 + binding.radarScanView.setDegreeValue(degree) + } + } + + override fun onDestroy() { + super.onDestroy() + soundPool.autoPause() + locationKit.stopLocation() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/common/detector/gd/bean/MarkerBean.java b/app/src/main/java/com/casic/common/detector/gd/bean/MarkerBean.java index 7a18c20..e7ecc60 100644 --- a/app/src/main/java/com/casic/common/detector/gd/bean/MarkerBean.java +++ b/app/src/main/java/com/casic/common/detector/gd/bean/MarkerBean.java @@ -14,7 +14,7 @@ private String pipelineDiameter; // 管线直径 private String pipelineMaterial; // 管材 private String buryMethod; // 埋设方式 - private String buryDepth; // 埋深 + private String buryDepth; // 管线埋深 private String area; // 所属区域 private String line; // 所属线路 private String road; // 所属道路