Newer
Older
Detector / app / src / main / assets / 审计版代码备份.kt
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 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.callback.OnGetLocationListener
import com.casic.common.detector.gd.databinding.ActivitySearchMarkerAuditBinding
import com.casic.common.detector.gd.utils.LocaleConstant
import com.casic.common.detector.gd.utils.LocationKit
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.base.KotlinBaseActivity
import com.pengxh.kt.lite.extensions.show
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.Timer
import java.util.TimerTask
import kotlin.math.atan2

class SearchMarkerActivity : KotlinBaseActivity<ActivitySearchMarkerAuditBinding>(),
    SensorEventListener {

    private val kTag = "SearchMarkerActivity"
    private val context = this
    private val locationKit by lazy { LocationKit(this) }
    private val sensorManager by lazy { getSystemService(SENSOR_SERVICE) as SensorManager }
    private val markerBeanDao by lazy { BaseApplication.Companion.get().dataBase.markerBeanDao() }
    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 nearestMarkerId = ""//探测不到标识器的时候计算出来的最近的标识器ID
    private var gravity: FloatArray? = null
    private var geomagnetic: FloatArray? = null
    private lateinit var searchSignalEnergyTimer: Timer

    override fun initOnCreate(savedInstanceState: Bundle?) {
        val 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)
            }
        })

        searchSignalEnergyTimer = Timer()
        searchSignalEnergyTimer.schedule(object : TimerTask() {
            override fun run() {
                soundPool.play(fastSoundResourceId, 1f, 1f, 0, 0, 1f)
            }
        }, 0, 100)
    }

    override fun initEvent() {
        binding.markerInfoButton.setOnClickListener {
            //查库
            val result = markerBeanDao.queryMarkerById(nearestMarkerId)
            if (result.isNotEmpty()) {
                MarkerDetailDialog(this).setMarker(result.first()).show()
            } else {
                NewMarkerDetailDialog(this, nearestMarkerId)
            }
        }
    }

    /**
     * 计算并渲染数据点。点太多采用协程计算,不然会有点卡顿。默认2s计算一次
     * @param location 定位点(RTK获取)
     * */
    private fun renderDataPoint(location: AMapLocation) {
        val longitude = location.longitude
        val latitude = location.latitude
        lifecycleScope.launch(Dispatchers.IO) {
            val dataPoints = ArrayList<RadarScanView.DataPoint>()
            markerBeanDao.loadAll().forEach {
                val distance = AMapUtils.calculateLineDistance(
                    LatLng(it.lat.toDouble(), it.lng.toDouble()), LatLng(latitude, longitude)
                )
                val formatDistance = "%.2f".format(distance).toFloat()
                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 {
                            nearestMarkerId = point.markerId
                            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(): ActivitySearchMarkerAuditBinding {
        return ActivitySearchMarkerAuditBinding.inflate(layoutInflater)
    }

    override fun observeRequestState() {

    }

    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()
        searchSignalEnergyTimer.cancel()
        soundPool.release()
        locationKit.stopLocation()
    }
}