diff --git a/app/build.gradle b/app/build.gradle index 9d0f82e..feb5ca9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -20,8 +20,8 @@ applicationId "com.casic.birmm.inspect" minSdkVersion 23 targetSdkVersion 33 - versionCode 1071 - versionName "1.0.7.1" + versionCode 1072 + versionName "1.0.7.2" } buildTypes { diff --git a/app/build.gradle b/app/build.gradle index 9d0f82e..feb5ca9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -20,8 +20,8 @@ applicationId "com.casic.birmm.inspect" minSdkVersion 23 targetSdkVersion 33 - versionCode 1071 - versionName "1.0.7.1" + versionCode 1072 + versionName "1.0.7.2" } buildTypes { diff --git a/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt b/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt index 30b8f28..12c92e6 100644 --- a/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt @@ -1,12 +1,5 @@ package com.casic.birmm.inspect.extensions -import com.amap.api.maps.model.LatLng -import com.amap.api.services.core.LatLonPoint -import com.amap.api.services.route.DistanceSearch -import com.casic.birmm.inspect.base.BaseApplication -import com.casic.birmm.inspect.callback.OnDistanceSearchListener -import java.text.DecimalFormat - /** * ArrayList扩展方法 */ @@ -32,39 +25,4 @@ result.add(it) } return result -} - -private val distanceSearch by lazy { DistanceSearch(BaseApplication.get()) } -private val distanceQuery by lazy { DistanceSearch.DistanceQuery() } -private val decimalFormat by lazy { DecimalFormat("#.##") } - -fun ArrayList.calculateDistance(listener: OnDistanceSearchListener) { - if (this.isEmpty()) { - listener.onDistanceSearched("0.00") - } - - val last = this.last() - val dest = LatLonPoint(last.latitude, last.longitude) - - //去掉最后一个点 - this.removeLast() - val latLonPoints: ArrayList = ArrayList() - this.forEach { - latLonPoints.add(LatLonPoint(it.latitude, it.longitude)) - } - - distanceQuery.origins = latLonPoints - distanceQuery.destination = dest - distanceQuery.type = DistanceSearch.TYPE_WALK_DISTANCE - distanceSearch.calculateRouteDistanceAsyn(distanceQuery) - distanceSearch.setDistanceSearchListener { distanceResult, errorCode -> - if (errorCode == 1000) { - //DistanceResult返回的是单位是米 - val temp = distanceResult.distanceResults[0].distance - val distance = temp / 1000 - listener.onDistanceSearched(decimalFormat.format(distance)) - } else { - listener.onDistanceSearched("0.00") - } - } } \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 9d0f82e..feb5ca9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -20,8 +20,8 @@ applicationId "com.casic.birmm.inspect" minSdkVersion 23 targetSdkVersion 33 - versionCode 1071 - versionName "1.0.7.1" + versionCode 1072 + versionName "1.0.7.2" } buildTypes { diff --git a/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt b/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt index 30b8f28..12c92e6 100644 --- a/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt @@ -1,12 +1,5 @@ package com.casic.birmm.inspect.extensions -import com.amap.api.maps.model.LatLng -import com.amap.api.services.core.LatLonPoint -import com.amap.api.services.route.DistanceSearch -import com.casic.birmm.inspect.base.BaseApplication -import com.casic.birmm.inspect.callback.OnDistanceSearchListener -import java.text.DecimalFormat - /** * ArrayList扩展方法 */ @@ -32,39 +25,4 @@ result.add(it) } return result -} - -private val distanceSearch by lazy { DistanceSearch(BaseApplication.get()) } -private val distanceQuery by lazy { DistanceSearch.DistanceQuery() } -private val decimalFormat by lazy { DecimalFormat("#.##") } - -fun ArrayList.calculateDistance(listener: OnDistanceSearchListener) { - if (this.isEmpty()) { - listener.onDistanceSearched("0.00") - } - - val last = this.last() - val dest = LatLonPoint(last.latitude, last.longitude) - - //去掉最后一个点 - this.removeLast() - val latLonPoints: ArrayList = ArrayList() - this.forEach { - latLonPoints.add(LatLonPoint(it.latitude, it.longitude)) - } - - distanceQuery.origins = latLonPoints - distanceQuery.destination = dest - distanceQuery.type = DistanceSearch.TYPE_WALK_DISTANCE - distanceSearch.calculateRouteDistanceAsyn(distanceQuery) - distanceSearch.setDistanceSearchListener { distanceResult, errorCode -> - if (errorCode == 1000) { - //DistanceResult返回的是单位是米 - val temp = distanceResult.distanceResults[0].distance - val distance = temp / 1000 - listener.onDistanceSearched(decimalFormat.format(distance)) - } else { - listener.onDistanceSearched("0.00") - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt index d5b1bc0..13b752f 100644 --- a/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt +++ b/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt @@ -2,9 +2,14 @@ import android.bluetooth.BluetoothGatt import android.bluetooth.BluetoothGattCharacteristic +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.ServiceConnection import android.graphics.Color import android.os.Bundle import android.os.Handler +import android.os.IBinder import android.os.Message import android.os.Vibrator import android.util.Log @@ -33,6 +38,7 @@ import com.casic.birmm.inspect.extensions.toDeviceCode import com.casic.birmm.inspect.extensions.toDeviceModel import com.casic.birmm.inspect.model.NewInspectionModel +import com.casic.birmm.inspect.service.LocationService import com.casic.birmm.inspect.utils.LocaleConstant import com.casic.birmm.inspect.utils.LocationHub import com.casic.birmm.inspect.utils.SoundPoolHelper @@ -99,7 +105,8 @@ private val kTag = "HomePageFragment" private val bleManager by lazy { BleManager.getInstance() } - private val latLngs = LinkedList() + private val newModel by lazy { NewInspectionModel() }//新建巡检数据结构模型 + private val latLngList by lazy { LinkedList() } private lateinit var userName: String private lateinit var eventViewModel: EventViewModel private lateinit var inspectionViewModel: InspectionViewModel @@ -108,7 +115,6 @@ private lateinit var writeUuid: String private lateinit var notifyUuid: String private var vibrator: Vibrator? = null - private var newModel: NewInspectionModel? = null//新建巡检数据结构模型 private var connectedDevice: BleDevice? = null private var isGeneratingTask = false private var alarmCount = 0 @@ -147,49 +153,19 @@ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isCompassEnabled = true uiSettings.isZoomControlsEnabled = true + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 //显示定位小蓝点 val locationStyle = MyLocationStyle() - locationStyle.showMyLocation(true)//设置是否显示定位小蓝点 + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + //定位、移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE) aMap.myLocationStyle = locationStyle aMap.isMyLocationEnabled = true aMap.mapType = AMap.MAP_TYPE_NORMAL - LocationHub.get.getLocationByAMap(requireContext(), object : LocationHub.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - "当前信号弱,无法定位".show(requireContext()) - return - } - - val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) - - //移动到指定经纬度 - val cameraPosition = CameraPosition(latLng, 16f, 0f, 0f) - val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) - aMap.animateCamera(cameraUpdate, 1500, null) - - //newInspectionModel已完成初始化,说明已经新建巡检任务,数据可以开始保存了 - if (newModel != null) { - //设置巡检起点 - if (newModel!!.startAddress.isEmpty()) { - newModel!!.startAddress = aMapLocation.address - } - - //巡检终点每次定位都覆盖,降低调用sdk频率 - newModel!!.endAddress = aMapLocation.address - - latLngs.add(latLng) - - //绘制线 - aMap.addPolyline( - PolylineOptions().addAll(latLngs).width(10f).color(Color.RED) - ) - } - } - }) - //UserName userName = SaveKeyValues.getValue(LocaleConstant.USER_NAME, "").toString() @@ -217,8 +193,11 @@ is LoadState.Success -> { LoadingDialogHub.dismiss() + //清空newModel + newModel.clearCache() + //结束任务就清空轨迹 - latLngs.clear() + latLngList.clear() aMap.clear() //按钮状态 @@ -248,16 +227,25 @@ binding.inspectNameView.text = value binding.inspectTimeView.text = startTime - newModel = NewInspectionModel( - currentTimeMillis.id(), value, - startTime, "", currentTimeMillis.timestampToDate(), - 0.0, 0.0, "", 0.0, 0.0, "", - ArrayList(), userName - ) + newModel.id = currentTimeMillis.id() + newModel.name = value + newModel.startTime = startTime + newModel.date = currentTimeMillis.timestampToDate() + newModel.user = userName //按钮状态 binding.stopInspectButton.isEnabled = true binding.addInspectionButton.isEnabled = false + + locationService?.startLocation(object : LocationHub.ILocationListener { + override fun onAMapLocationGet(aMapLocation: AMapLocation) { + drawTaskRoute(aMapLocation) + } + + override fun onAMapLocationError() { + "当前信号弱,无法定位".show(requireContext()) + } + }) } override fun onCancelClick() { @@ -284,11 +272,11 @@ requireContext().navigatePageTo( addAll( position.toString(), - newModel!!.id, - newModel!!.name, + newModel.id, + newModel.name, connectedDeviceCode, - latLngs.last.longitude.toString(), - latLngs.last.latitude.toString() + newModel.routes.last.longitude.toString(), + newModel.routes.last.latitude.toString() ) ) } @@ -296,6 +284,33 @@ } } + private fun drawTaskRoute(aMapLocation: AMapLocation) { + Log.d(kTag, "${aMapLocation.latitude}, ${aMapLocation.longitude}") + val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) + + //移动到指定经纬度 + val cameraPosition = CameraPosition(latLng, 15f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + + //stopInspectButton isEnabled,说明已经新建巡检任务,数据可以开始保存了 + if (binding.stopInspectButton.isEnabled) { + latLngList.add(latLng) + newModel.routes = latLngList + + //设置巡检起点 + if (newModel.startAddress.isNullOrEmpty()) { + newModel.startAddress = aMapLocation.address + } + + //巡检终点每次定位都覆盖,降低调用sdk频率 + newModel.endAddress = aMapLocation.address + + //绘制线 + aMap.addPolyline(PolylineOptions().addAll(newModel.routes).width(10f).color(Color.RED)) + } + } + private fun menuButtonEvent() { //结束巡检 binding.stopInspectButton.setOnClickListener { @@ -345,8 +360,6 @@ //关闭数据传送指令 bleManager.disconnectAllDevice() - latLngs.clear() - aMap.clear()//清除原来的路线 SaveKeyValues.removeKey(LocaleConstant.DEVICE_CODE) withContext(Dispatchers.Main) { binding.currentValueView.text = "--" @@ -588,44 +601,41 @@ * * 如果保存到本地,则需要设置标识位,然后finish当前页面并提示 * */ - if (newModel == null) { - "保存失败".show(requireContext()) - return - } - - // 上传巡检位置点 - for (i in 0 until latLngs.size) { - newModel!!.routes.add(latLngs[i]) + val routes = newModel.routes + for (i in 0 until routes.size) { //上传点位 routeViewModel.uploadRoutePoint( - newModel!!.id, - latLngs[i], - System.currentTimeMillis().timestampToCompleteDate() + newModel.id, routes[i], System.currentTimeMillis().timestampToCompleteDate() ) } - val first = latLngs.first - val last = latLngs.last - newModel!!.routes.calculateDistance(object : OnDistanceSearchListener { - override fun onDistanceSearched(distance: String) { - inspectionViewModel.addInspection( - id = newModel!!.id, - deviceCode = connectedDeviceCode, - name = newModel!!.name, - startTime = newModel!!.startTime, - endTime = System.currentTimeMillis().timestampToCompleteDate(), - date = newModel!!.date, - startLng = first.longitude, - startLat = first.latitude, - newModel!!.startAddress, - endLng = last.longitude, - endLat = last.latitude, - newModel!!.endAddress, - distance, - user = userName - ) - } - }) + try { + val first = routes.first + val last = routes.last + routes.calculateDistance(object : OnDistanceSearchListener { + override fun onDistanceSearched(distance: String) { + inspectionViewModel.addInspection( + id = newModel.id, + deviceCode = connectedDeviceCode, + name = newModel.name, + startTime = newModel.startTime, + endTime = System.currentTimeMillis().timestampToCompleteDate(), + date = newModel.date, + startLng = first.longitude, + startLat = first.latitude, + startAddress = newModel.startAddress, + endLng = last.longitude, + endLat = last.latitude, + endAddress = newModel.endAddress, + distance, + user = userName + ) + } + }) + } catch (e: NoSuchElementException) { + e.printStackTrace() + "无定位数据,保存任务失败".show(requireContext()) + } } /** @@ -657,10 +667,6 @@ //如果连续超过10个报警,自动生成报警事件 alarmCount++ if (alarmCount >= 10) { - if (newModel == null) { - "没有巡检任务,无法自动记录报警".show(requireContext()) - return - } generateAlarmTask(dataModel.maxPotency) } } @@ -680,12 +686,12 @@ eventViewModel.addEventTask( id = UUID.randomUUID().toString(), - inspectionId = newModel!!.id, - name = newModel!!.name, + inspectionId = newModel.id, + name = newModel.name, createTime = System.currentTimeMillis().timestampToCompleteDate(), type = "报警事件", - lng = latLngs.last.longitude, - lat = latLngs.last.latitude, + lng = newModel.routes.last.longitude, + lat = newModel.routes.last.latitude, data = maxValue, images = "", description = "自动报警记录", @@ -713,11 +719,28 @@ } //设置标题和时间 - if (newModel == null) { - return + binding.inspectNameView.text = newModel.name + binding.inspectTimeView.text = newModel.startTime + + //绑定定位服务 + Intent(requireContext(), LocationService::class.java).also { + requireContext().bindService(it, serviceConnection, Context.BIND_AUTO_CREATE) } - binding.inspectNameView.text = newModel!!.name - binding.inspectTimeView.text = newModel!!.startTime + } + + private var locationService: LocationService? = null + + private val serviceConnection = object : ServiceConnection { + override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) { + if (iBinder is LocationService.ServiceBinder) { + locationService = iBinder.getLocationService() + Log.d(kTag, "onServiceConnected: ") + } + } + + override fun onServiceDisconnected(name: ComponentName?) { + "定位服务已断开".show(requireContext()) + } } override fun onPause() { diff --git a/app/build.gradle b/app/build.gradle index 9d0f82e..feb5ca9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -20,8 +20,8 @@ applicationId "com.casic.birmm.inspect" minSdkVersion 23 targetSdkVersion 33 - versionCode 1071 - versionName "1.0.7.1" + versionCode 1072 + versionName "1.0.7.2" } buildTypes { diff --git a/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt b/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt index 30b8f28..12c92e6 100644 --- a/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt @@ -1,12 +1,5 @@ package com.casic.birmm.inspect.extensions -import com.amap.api.maps.model.LatLng -import com.amap.api.services.core.LatLonPoint -import com.amap.api.services.route.DistanceSearch -import com.casic.birmm.inspect.base.BaseApplication -import com.casic.birmm.inspect.callback.OnDistanceSearchListener -import java.text.DecimalFormat - /** * ArrayList扩展方法 */ @@ -32,39 +25,4 @@ result.add(it) } return result -} - -private val distanceSearch by lazy { DistanceSearch(BaseApplication.get()) } -private val distanceQuery by lazy { DistanceSearch.DistanceQuery() } -private val decimalFormat by lazy { DecimalFormat("#.##") } - -fun ArrayList.calculateDistance(listener: OnDistanceSearchListener) { - if (this.isEmpty()) { - listener.onDistanceSearched("0.00") - } - - val last = this.last() - val dest = LatLonPoint(last.latitude, last.longitude) - - //去掉最后一个点 - this.removeLast() - val latLonPoints: ArrayList = ArrayList() - this.forEach { - latLonPoints.add(LatLonPoint(it.latitude, it.longitude)) - } - - distanceQuery.origins = latLonPoints - distanceQuery.destination = dest - distanceQuery.type = DistanceSearch.TYPE_WALK_DISTANCE - distanceSearch.calculateRouteDistanceAsyn(distanceQuery) - distanceSearch.setDistanceSearchListener { distanceResult, errorCode -> - if (errorCode == 1000) { - //DistanceResult返回的是单位是米 - val temp = distanceResult.distanceResults[0].distance - val distance = temp / 1000 - listener.onDistanceSearched(decimalFormat.format(distance)) - } else { - listener.onDistanceSearched("0.00") - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt index d5b1bc0..13b752f 100644 --- a/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt +++ b/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt @@ -2,9 +2,14 @@ import android.bluetooth.BluetoothGatt import android.bluetooth.BluetoothGattCharacteristic +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.ServiceConnection import android.graphics.Color import android.os.Bundle import android.os.Handler +import android.os.IBinder import android.os.Message import android.os.Vibrator import android.util.Log @@ -33,6 +38,7 @@ import com.casic.birmm.inspect.extensions.toDeviceCode import com.casic.birmm.inspect.extensions.toDeviceModel import com.casic.birmm.inspect.model.NewInspectionModel +import com.casic.birmm.inspect.service.LocationService import com.casic.birmm.inspect.utils.LocaleConstant import com.casic.birmm.inspect.utils.LocationHub import com.casic.birmm.inspect.utils.SoundPoolHelper @@ -99,7 +105,8 @@ private val kTag = "HomePageFragment" private val bleManager by lazy { BleManager.getInstance() } - private val latLngs = LinkedList() + private val newModel by lazy { NewInspectionModel() }//新建巡检数据结构模型 + private val latLngList by lazy { LinkedList() } private lateinit var userName: String private lateinit var eventViewModel: EventViewModel private lateinit var inspectionViewModel: InspectionViewModel @@ -108,7 +115,6 @@ private lateinit var writeUuid: String private lateinit var notifyUuid: String private var vibrator: Vibrator? = null - private var newModel: NewInspectionModel? = null//新建巡检数据结构模型 private var connectedDevice: BleDevice? = null private var isGeneratingTask = false private var alarmCount = 0 @@ -147,49 +153,19 @@ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isCompassEnabled = true uiSettings.isZoomControlsEnabled = true + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 //显示定位小蓝点 val locationStyle = MyLocationStyle() - locationStyle.showMyLocation(true)//设置是否显示定位小蓝点 + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + //定位、移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE) aMap.myLocationStyle = locationStyle aMap.isMyLocationEnabled = true aMap.mapType = AMap.MAP_TYPE_NORMAL - LocationHub.get.getLocationByAMap(requireContext(), object : LocationHub.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - "当前信号弱,无法定位".show(requireContext()) - return - } - - val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) - - //移动到指定经纬度 - val cameraPosition = CameraPosition(latLng, 16f, 0f, 0f) - val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) - aMap.animateCamera(cameraUpdate, 1500, null) - - //newInspectionModel已完成初始化,说明已经新建巡检任务,数据可以开始保存了 - if (newModel != null) { - //设置巡检起点 - if (newModel!!.startAddress.isEmpty()) { - newModel!!.startAddress = aMapLocation.address - } - - //巡检终点每次定位都覆盖,降低调用sdk频率 - newModel!!.endAddress = aMapLocation.address - - latLngs.add(latLng) - - //绘制线 - aMap.addPolyline( - PolylineOptions().addAll(latLngs).width(10f).color(Color.RED) - ) - } - } - }) - //UserName userName = SaveKeyValues.getValue(LocaleConstant.USER_NAME, "").toString() @@ -217,8 +193,11 @@ is LoadState.Success -> { LoadingDialogHub.dismiss() + //清空newModel + newModel.clearCache() + //结束任务就清空轨迹 - latLngs.clear() + latLngList.clear() aMap.clear() //按钮状态 @@ -248,16 +227,25 @@ binding.inspectNameView.text = value binding.inspectTimeView.text = startTime - newModel = NewInspectionModel( - currentTimeMillis.id(), value, - startTime, "", currentTimeMillis.timestampToDate(), - 0.0, 0.0, "", 0.0, 0.0, "", - ArrayList(), userName - ) + newModel.id = currentTimeMillis.id() + newModel.name = value + newModel.startTime = startTime + newModel.date = currentTimeMillis.timestampToDate() + newModel.user = userName //按钮状态 binding.stopInspectButton.isEnabled = true binding.addInspectionButton.isEnabled = false + + locationService?.startLocation(object : LocationHub.ILocationListener { + override fun onAMapLocationGet(aMapLocation: AMapLocation) { + drawTaskRoute(aMapLocation) + } + + override fun onAMapLocationError() { + "当前信号弱,无法定位".show(requireContext()) + } + }) } override fun onCancelClick() { @@ -284,11 +272,11 @@ requireContext().navigatePageTo( addAll( position.toString(), - newModel!!.id, - newModel!!.name, + newModel.id, + newModel.name, connectedDeviceCode, - latLngs.last.longitude.toString(), - latLngs.last.latitude.toString() + newModel.routes.last.longitude.toString(), + newModel.routes.last.latitude.toString() ) ) } @@ -296,6 +284,33 @@ } } + private fun drawTaskRoute(aMapLocation: AMapLocation) { + Log.d(kTag, "${aMapLocation.latitude}, ${aMapLocation.longitude}") + val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) + + //移动到指定经纬度 + val cameraPosition = CameraPosition(latLng, 15f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + + //stopInspectButton isEnabled,说明已经新建巡检任务,数据可以开始保存了 + if (binding.stopInspectButton.isEnabled) { + latLngList.add(latLng) + newModel.routes = latLngList + + //设置巡检起点 + if (newModel.startAddress.isNullOrEmpty()) { + newModel.startAddress = aMapLocation.address + } + + //巡检终点每次定位都覆盖,降低调用sdk频率 + newModel.endAddress = aMapLocation.address + + //绘制线 + aMap.addPolyline(PolylineOptions().addAll(newModel.routes).width(10f).color(Color.RED)) + } + } + private fun menuButtonEvent() { //结束巡检 binding.stopInspectButton.setOnClickListener { @@ -345,8 +360,6 @@ //关闭数据传送指令 bleManager.disconnectAllDevice() - latLngs.clear() - aMap.clear()//清除原来的路线 SaveKeyValues.removeKey(LocaleConstant.DEVICE_CODE) withContext(Dispatchers.Main) { binding.currentValueView.text = "--" @@ -588,44 +601,41 @@ * * 如果保存到本地,则需要设置标识位,然后finish当前页面并提示 * */ - if (newModel == null) { - "保存失败".show(requireContext()) - return - } - - // 上传巡检位置点 - for (i in 0 until latLngs.size) { - newModel!!.routes.add(latLngs[i]) + val routes = newModel.routes + for (i in 0 until routes.size) { //上传点位 routeViewModel.uploadRoutePoint( - newModel!!.id, - latLngs[i], - System.currentTimeMillis().timestampToCompleteDate() + newModel.id, routes[i], System.currentTimeMillis().timestampToCompleteDate() ) } - val first = latLngs.first - val last = latLngs.last - newModel!!.routes.calculateDistance(object : OnDistanceSearchListener { - override fun onDistanceSearched(distance: String) { - inspectionViewModel.addInspection( - id = newModel!!.id, - deviceCode = connectedDeviceCode, - name = newModel!!.name, - startTime = newModel!!.startTime, - endTime = System.currentTimeMillis().timestampToCompleteDate(), - date = newModel!!.date, - startLng = first.longitude, - startLat = first.latitude, - newModel!!.startAddress, - endLng = last.longitude, - endLat = last.latitude, - newModel!!.endAddress, - distance, - user = userName - ) - } - }) + try { + val first = routes.first + val last = routes.last + routes.calculateDistance(object : OnDistanceSearchListener { + override fun onDistanceSearched(distance: String) { + inspectionViewModel.addInspection( + id = newModel.id, + deviceCode = connectedDeviceCode, + name = newModel.name, + startTime = newModel.startTime, + endTime = System.currentTimeMillis().timestampToCompleteDate(), + date = newModel.date, + startLng = first.longitude, + startLat = first.latitude, + startAddress = newModel.startAddress, + endLng = last.longitude, + endLat = last.latitude, + endAddress = newModel.endAddress, + distance, + user = userName + ) + } + }) + } catch (e: NoSuchElementException) { + e.printStackTrace() + "无定位数据,保存任务失败".show(requireContext()) + } } /** @@ -657,10 +667,6 @@ //如果连续超过10个报警,自动生成报警事件 alarmCount++ if (alarmCount >= 10) { - if (newModel == null) { - "没有巡检任务,无法自动记录报警".show(requireContext()) - return - } generateAlarmTask(dataModel.maxPotency) } } @@ -680,12 +686,12 @@ eventViewModel.addEventTask( id = UUID.randomUUID().toString(), - inspectionId = newModel!!.id, - name = newModel!!.name, + inspectionId = newModel.id, + name = newModel.name, createTime = System.currentTimeMillis().timestampToCompleteDate(), type = "报警事件", - lng = latLngs.last.longitude, - lat = latLngs.last.latitude, + lng = newModel.routes.last.longitude, + lat = newModel.routes.last.latitude, data = maxValue, images = "", description = "自动报警记录", @@ -713,11 +719,28 @@ } //设置标题和时间 - if (newModel == null) { - return + binding.inspectNameView.text = newModel.name + binding.inspectTimeView.text = newModel.startTime + + //绑定定位服务 + Intent(requireContext(), LocationService::class.java).also { + requireContext().bindService(it, serviceConnection, Context.BIND_AUTO_CREATE) } - binding.inspectNameView.text = newModel!!.name - binding.inspectTimeView.text = newModel!!.startTime + } + + private var locationService: LocationService? = null + + private val serviceConnection = object : ServiceConnection { + override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) { + if (iBinder is LocationService.ServiceBinder) { + locationService = iBinder.getLocationService() + Log.d(kTag, "onServiceConnected: ") + } + } + + override fun onServiceDisconnected(name: ComponentName?) { + "定位服务已断开".show(requireContext()) + } } override fun onPause() { diff --git a/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.java b/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.java new file mode 100644 index 0000000..f09810f --- /dev/null +++ b/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.java @@ -0,0 +1,141 @@ +package com.casic.birmm.inspect.model; + +import com.amap.api.maps.model.LatLng; + +import java.util.LinkedList; + +public class NewInspectionModel { + private String id; + private String name; + private String startTime; + private String endTime; + private String date; + private String startLng; + private String startLat; + private String startAddress; + private String endLng; + private String endLat; + private String endAddress; + private LinkedList routes; + private String user; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + + public String getEndTime() { + return endTime; + } + + public void setEndTime(String endTime) { + this.endTime = endTime; + } + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } + + public String getStartLng() { + return startLng; + } + + public void setStartLng(String startLng) { + this.startLng = startLng; + } + + public String getStartLat() { + return startLat; + } + + public void setStartLat(String startLat) { + this.startLat = startLat; + } + + public String getStartAddress() { + return startAddress; + } + + public void setStartAddress(String startAddress) { + this.startAddress = startAddress; + } + + public String getEndLng() { + return endLng; + } + + public void setEndLng(String endLng) { + this.endLng = endLng; + } + + public String getEndLat() { + return endLat; + } + + public void setEndLat(String endLat) { + this.endLat = endLat; + } + + public String getEndAddress() { + return endAddress; + } + + public void setEndAddress(String endAddress) { + this.endAddress = endAddress; + } + + public LinkedList getRoutes() { + return routes; + } + + public void setRoutes(LinkedList routes) { + this.routes = routes; + } + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public void clearCache() { + this.id = ""; + this.name = ""; + this.startTime = ""; + this.endTime = ""; + this.date = ""; + this.startLng = ""; + this.startLat = ""; + this.startAddress = ""; + this.endLng = ""; + this.endLat = ""; + this.endAddress = ""; + this.routes.clear(); + this.user = ""; + } +} \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 9d0f82e..feb5ca9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -20,8 +20,8 @@ applicationId "com.casic.birmm.inspect" minSdkVersion 23 targetSdkVersion 33 - versionCode 1071 - versionName "1.0.7.1" + versionCode 1072 + versionName "1.0.7.2" } buildTypes { diff --git a/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt b/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt index 30b8f28..12c92e6 100644 --- a/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt @@ -1,12 +1,5 @@ package com.casic.birmm.inspect.extensions -import com.amap.api.maps.model.LatLng -import com.amap.api.services.core.LatLonPoint -import com.amap.api.services.route.DistanceSearch -import com.casic.birmm.inspect.base.BaseApplication -import com.casic.birmm.inspect.callback.OnDistanceSearchListener -import java.text.DecimalFormat - /** * ArrayList扩展方法 */ @@ -32,39 +25,4 @@ result.add(it) } return result -} - -private val distanceSearch by lazy { DistanceSearch(BaseApplication.get()) } -private val distanceQuery by lazy { DistanceSearch.DistanceQuery() } -private val decimalFormat by lazy { DecimalFormat("#.##") } - -fun ArrayList.calculateDistance(listener: OnDistanceSearchListener) { - if (this.isEmpty()) { - listener.onDistanceSearched("0.00") - } - - val last = this.last() - val dest = LatLonPoint(last.latitude, last.longitude) - - //去掉最后一个点 - this.removeLast() - val latLonPoints: ArrayList = ArrayList() - this.forEach { - latLonPoints.add(LatLonPoint(it.latitude, it.longitude)) - } - - distanceQuery.origins = latLonPoints - distanceQuery.destination = dest - distanceQuery.type = DistanceSearch.TYPE_WALK_DISTANCE - distanceSearch.calculateRouteDistanceAsyn(distanceQuery) - distanceSearch.setDistanceSearchListener { distanceResult, errorCode -> - if (errorCode == 1000) { - //DistanceResult返回的是单位是米 - val temp = distanceResult.distanceResults[0].distance - val distance = temp / 1000 - listener.onDistanceSearched(decimalFormat.format(distance)) - } else { - listener.onDistanceSearched("0.00") - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt index d5b1bc0..13b752f 100644 --- a/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt +++ b/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt @@ -2,9 +2,14 @@ import android.bluetooth.BluetoothGatt import android.bluetooth.BluetoothGattCharacteristic +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.ServiceConnection import android.graphics.Color import android.os.Bundle import android.os.Handler +import android.os.IBinder import android.os.Message import android.os.Vibrator import android.util.Log @@ -33,6 +38,7 @@ import com.casic.birmm.inspect.extensions.toDeviceCode import com.casic.birmm.inspect.extensions.toDeviceModel import com.casic.birmm.inspect.model.NewInspectionModel +import com.casic.birmm.inspect.service.LocationService import com.casic.birmm.inspect.utils.LocaleConstant import com.casic.birmm.inspect.utils.LocationHub import com.casic.birmm.inspect.utils.SoundPoolHelper @@ -99,7 +105,8 @@ private val kTag = "HomePageFragment" private val bleManager by lazy { BleManager.getInstance() } - private val latLngs = LinkedList() + private val newModel by lazy { NewInspectionModel() }//新建巡检数据结构模型 + private val latLngList by lazy { LinkedList() } private lateinit var userName: String private lateinit var eventViewModel: EventViewModel private lateinit var inspectionViewModel: InspectionViewModel @@ -108,7 +115,6 @@ private lateinit var writeUuid: String private lateinit var notifyUuid: String private var vibrator: Vibrator? = null - private var newModel: NewInspectionModel? = null//新建巡检数据结构模型 private var connectedDevice: BleDevice? = null private var isGeneratingTask = false private var alarmCount = 0 @@ -147,49 +153,19 @@ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isCompassEnabled = true uiSettings.isZoomControlsEnabled = true + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 //显示定位小蓝点 val locationStyle = MyLocationStyle() - locationStyle.showMyLocation(true)//设置是否显示定位小蓝点 + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + //定位、移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE) aMap.myLocationStyle = locationStyle aMap.isMyLocationEnabled = true aMap.mapType = AMap.MAP_TYPE_NORMAL - LocationHub.get.getLocationByAMap(requireContext(), object : LocationHub.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - "当前信号弱,无法定位".show(requireContext()) - return - } - - val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) - - //移动到指定经纬度 - val cameraPosition = CameraPosition(latLng, 16f, 0f, 0f) - val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) - aMap.animateCamera(cameraUpdate, 1500, null) - - //newInspectionModel已完成初始化,说明已经新建巡检任务,数据可以开始保存了 - if (newModel != null) { - //设置巡检起点 - if (newModel!!.startAddress.isEmpty()) { - newModel!!.startAddress = aMapLocation.address - } - - //巡检终点每次定位都覆盖,降低调用sdk频率 - newModel!!.endAddress = aMapLocation.address - - latLngs.add(latLng) - - //绘制线 - aMap.addPolyline( - PolylineOptions().addAll(latLngs).width(10f).color(Color.RED) - ) - } - } - }) - //UserName userName = SaveKeyValues.getValue(LocaleConstant.USER_NAME, "").toString() @@ -217,8 +193,11 @@ is LoadState.Success -> { LoadingDialogHub.dismiss() + //清空newModel + newModel.clearCache() + //结束任务就清空轨迹 - latLngs.clear() + latLngList.clear() aMap.clear() //按钮状态 @@ -248,16 +227,25 @@ binding.inspectNameView.text = value binding.inspectTimeView.text = startTime - newModel = NewInspectionModel( - currentTimeMillis.id(), value, - startTime, "", currentTimeMillis.timestampToDate(), - 0.0, 0.0, "", 0.0, 0.0, "", - ArrayList(), userName - ) + newModel.id = currentTimeMillis.id() + newModel.name = value + newModel.startTime = startTime + newModel.date = currentTimeMillis.timestampToDate() + newModel.user = userName //按钮状态 binding.stopInspectButton.isEnabled = true binding.addInspectionButton.isEnabled = false + + locationService?.startLocation(object : LocationHub.ILocationListener { + override fun onAMapLocationGet(aMapLocation: AMapLocation) { + drawTaskRoute(aMapLocation) + } + + override fun onAMapLocationError() { + "当前信号弱,无法定位".show(requireContext()) + } + }) } override fun onCancelClick() { @@ -284,11 +272,11 @@ requireContext().navigatePageTo( addAll( position.toString(), - newModel!!.id, - newModel!!.name, + newModel.id, + newModel.name, connectedDeviceCode, - latLngs.last.longitude.toString(), - latLngs.last.latitude.toString() + newModel.routes.last.longitude.toString(), + newModel.routes.last.latitude.toString() ) ) } @@ -296,6 +284,33 @@ } } + private fun drawTaskRoute(aMapLocation: AMapLocation) { + Log.d(kTag, "${aMapLocation.latitude}, ${aMapLocation.longitude}") + val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) + + //移动到指定经纬度 + val cameraPosition = CameraPosition(latLng, 15f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + + //stopInspectButton isEnabled,说明已经新建巡检任务,数据可以开始保存了 + if (binding.stopInspectButton.isEnabled) { + latLngList.add(latLng) + newModel.routes = latLngList + + //设置巡检起点 + if (newModel.startAddress.isNullOrEmpty()) { + newModel.startAddress = aMapLocation.address + } + + //巡检终点每次定位都覆盖,降低调用sdk频率 + newModel.endAddress = aMapLocation.address + + //绘制线 + aMap.addPolyline(PolylineOptions().addAll(newModel.routes).width(10f).color(Color.RED)) + } + } + private fun menuButtonEvent() { //结束巡检 binding.stopInspectButton.setOnClickListener { @@ -345,8 +360,6 @@ //关闭数据传送指令 bleManager.disconnectAllDevice() - latLngs.clear() - aMap.clear()//清除原来的路线 SaveKeyValues.removeKey(LocaleConstant.DEVICE_CODE) withContext(Dispatchers.Main) { binding.currentValueView.text = "--" @@ -588,44 +601,41 @@ * * 如果保存到本地,则需要设置标识位,然后finish当前页面并提示 * */ - if (newModel == null) { - "保存失败".show(requireContext()) - return - } - - // 上传巡检位置点 - for (i in 0 until latLngs.size) { - newModel!!.routes.add(latLngs[i]) + val routes = newModel.routes + for (i in 0 until routes.size) { //上传点位 routeViewModel.uploadRoutePoint( - newModel!!.id, - latLngs[i], - System.currentTimeMillis().timestampToCompleteDate() + newModel.id, routes[i], System.currentTimeMillis().timestampToCompleteDate() ) } - val first = latLngs.first - val last = latLngs.last - newModel!!.routes.calculateDistance(object : OnDistanceSearchListener { - override fun onDistanceSearched(distance: String) { - inspectionViewModel.addInspection( - id = newModel!!.id, - deviceCode = connectedDeviceCode, - name = newModel!!.name, - startTime = newModel!!.startTime, - endTime = System.currentTimeMillis().timestampToCompleteDate(), - date = newModel!!.date, - startLng = first.longitude, - startLat = first.latitude, - newModel!!.startAddress, - endLng = last.longitude, - endLat = last.latitude, - newModel!!.endAddress, - distance, - user = userName - ) - } - }) + try { + val first = routes.first + val last = routes.last + routes.calculateDistance(object : OnDistanceSearchListener { + override fun onDistanceSearched(distance: String) { + inspectionViewModel.addInspection( + id = newModel.id, + deviceCode = connectedDeviceCode, + name = newModel.name, + startTime = newModel.startTime, + endTime = System.currentTimeMillis().timestampToCompleteDate(), + date = newModel.date, + startLng = first.longitude, + startLat = first.latitude, + startAddress = newModel.startAddress, + endLng = last.longitude, + endLat = last.latitude, + endAddress = newModel.endAddress, + distance, + user = userName + ) + } + }) + } catch (e: NoSuchElementException) { + e.printStackTrace() + "无定位数据,保存任务失败".show(requireContext()) + } } /** @@ -657,10 +667,6 @@ //如果连续超过10个报警,自动生成报警事件 alarmCount++ if (alarmCount >= 10) { - if (newModel == null) { - "没有巡检任务,无法自动记录报警".show(requireContext()) - return - } generateAlarmTask(dataModel.maxPotency) } } @@ -680,12 +686,12 @@ eventViewModel.addEventTask( id = UUID.randomUUID().toString(), - inspectionId = newModel!!.id, - name = newModel!!.name, + inspectionId = newModel.id, + name = newModel.name, createTime = System.currentTimeMillis().timestampToCompleteDate(), type = "报警事件", - lng = latLngs.last.longitude, - lat = latLngs.last.latitude, + lng = newModel.routes.last.longitude, + lat = newModel.routes.last.latitude, data = maxValue, images = "", description = "自动报警记录", @@ -713,11 +719,28 @@ } //设置标题和时间 - if (newModel == null) { - return + binding.inspectNameView.text = newModel.name + binding.inspectTimeView.text = newModel.startTime + + //绑定定位服务 + Intent(requireContext(), LocationService::class.java).also { + requireContext().bindService(it, serviceConnection, Context.BIND_AUTO_CREATE) } - binding.inspectNameView.text = newModel!!.name - binding.inspectTimeView.text = newModel!!.startTime + } + + private var locationService: LocationService? = null + + private val serviceConnection = object : ServiceConnection { + override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) { + if (iBinder is LocationService.ServiceBinder) { + locationService = iBinder.getLocationService() + Log.d(kTag, "onServiceConnected: ") + } + } + + override fun onServiceDisconnected(name: ComponentName?) { + "定位服务已断开".show(requireContext()) + } } override fun onPause() { diff --git a/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.java b/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.java new file mode 100644 index 0000000..f09810f --- /dev/null +++ b/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.java @@ -0,0 +1,141 @@ +package com.casic.birmm.inspect.model; + +import com.amap.api.maps.model.LatLng; + +import java.util.LinkedList; + +public class NewInspectionModel { + private String id; + private String name; + private String startTime; + private String endTime; + private String date; + private String startLng; + private String startLat; + private String startAddress; + private String endLng; + private String endLat; + private String endAddress; + private LinkedList routes; + private String user; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + + public String getEndTime() { + return endTime; + } + + public void setEndTime(String endTime) { + this.endTime = endTime; + } + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } + + public String getStartLng() { + return startLng; + } + + public void setStartLng(String startLng) { + this.startLng = startLng; + } + + public String getStartLat() { + return startLat; + } + + public void setStartLat(String startLat) { + this.startLat = startLat; + } + + public String getStartAddress() { + return startAddress; + } + + public void setStartAddress(String startAddress) { + this.startAddress = startAddress; + } + + public String getEndLng() { + return endLng; + } + + public void setEndLng(String endLng) { + this.endLng = endLng; + } + + public String getEndLat() { + return endLat; + } + + public void setEndLat(String endLat) { + this.endLat = endLat; + } + + public String getEndAddress() { + return endAddress; + } + + public void setEndAddress(String endAddress) { + this.endAddress = endAddress; + } + + public LinkedList getRoutes() { + return routes; + } + + public void setRoutes(LinkedList routes) { + this.routes = routes; + } + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public void clearCache() { + this.id = ""; + this.name = ""; + this.startTime = ""; + this.endTime = ""; + this.date = ""; + this.startLng = ""; + this.startLat = ""; + this.startAddress = ""; + this.endLng = ""; + this.endLat = ""; + this.endAddress = ""; + this.routes.clear(); + this.user = ""; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.kt b/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.kt deleted file mode 100644 index f08334a..0000000 --- a/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.birmm.inspect.model - -import com.amap.api.maps.model.LatLng - -data class NewInspectionModel( - var id: String, - var name: String, - var startTime: String, - var endTime: String, - var date: String, - var startLng: Double, - var startLat: Double, - var startAddress: String, - var endLng: Double, - var endLat: Double, - var endAddress: String, - var routes: ArrayList, - var user: String -) \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 9d0f82e..feb5ca9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -20,8 +20,8 @@ applicationId "com.casic.birmm.inspect" minSdkVersion 23 targetSdkVersion 33 - versionCode 1071 - versionName "1.0.7.1" + versionCode 1072 + versionName "1.0.7.2" } buildTypes { diff --git a/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt b/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt index 30b8f28..12c92e6 100644 --- a/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt @@ -1,12 +1,5 @@ package com.casic.birmm.inspect.extensions -import com.amap.api.maps.model.LatLng -import com.amap.api.services.core.LatLonPoint -import com.amap.api.services.route.DistanceSearch -import com.casic.birmm.inspect.base.BaseApplication -import com.casic.birmm.inspect.callback.OnDistanceSearchListener -import java.text.DecimalFormat - /** * ArrayList扩展方法 */ @@ -32,39 +25,4 @@ result.add(it) } return result -} - -private val distanceSearch by lazy { DistanceSearch(BaseApplication.get()) } -private val distanceQuery by lazy { DistanceSearch.DistanceQuery() } -private val decimalFormat by lazy { DecimalFormat("#.##") } - -fun ArrayList.calculateDistance(listener: OnDistanceSearchListener) { - if (this.isEmpty()) { - listener.onDistanceSearched("0.00") - } - - val last = this.last() - val dest = LatLonPoint(last.latitude, last.longitude) - - //去掉最后一个点 - this.removeLast() - val latLonPoints: ArrayList = ArrayList() - this.forEach { - latLonPoints.add(LatLonPoint(it.latitude, it.longitude)) - } - - distanceQuery.origins = latLonPoints - distanceQuery.destination = dest - distanceQuery.type = DistanceSearch.TYPE_WALK_DISTANCE - distanceSearch.calculateRouteDistanceAsyn(distanceQuery) - distanceSearch.setDistanceSearchListener { distanceResult, errorCode -> - if (errorCode == 1000) { - //DistanceResult返回的是单位是米 - val temp = distanceResult.distanceResults[0].distance - val distance = temp / 1000 - listener.onDistanceSearched(decimalFormat.format(distance)) - } else { - listener.onDistanceSearched("0.00") - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt index d5b1bc0..13b752f 100644 --- a/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt +++ b/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt @@ -2,9 +2,14 @@ import android.bluetooth.BluetoothGatt import android.bluetooth.BluetoothGattCharacteristic +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.ServiceConnection import android.graphics.Color import android.os.Bundle import android.os.Handler +import android.os.IBinder import android.os.Message import android.os.Vibrator import android.util.Log @@ -33,6 +38,7 @@ import com.casic.birmm.inspect.extensions.toDeviceCode import com.casic.birmm.inspect.extensions.toDeviceModel import com.casic.birmm.inspect.model.NewInspectionModel +import com.casic.birmm.inspect.service.LocationService import com.casic.birmm.inspect.utils.LocaleConstant import com.casic.birmm.inspect.utils.LocationHub import com.casic.birmm.inspect.utils.SoundPoolHelper @@ -99,7 +105,8 @@ private val kTag = "HomePageFragment" private val bleManager by lazy { BleManager.getInstance() } - private val latLngs = LinkedList() + private val newModel by lazy { NewInspectionModel() }//新建巡检数据结构模型 + private val latLngList by lazy { LinkedList() } private lateinit var userName: String private lateinit var eventViewModel: EventViewModel private lateinit var inspectionViewModel: InspectionViewModel @@ -108,7 +115,6 @@ private lateinit var writeUuid: String private lateinit var notifyUuid: String private var vibrator: Vibrator? = null - private var newModel: NewInspectionModel? = null//新建巡检数据结构模型 private var connectedDevice: BleDevice? = null private var isGeneratingTask = false private var alarmCount = 0 @@ -147,49 +153,19 @@ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isCompassEnabled = true uiSettings.isZoomControlsEnabled = true + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 //显示定位小蓝点 val locationStyle = MyLocationStyle() - locationStyle.showMyLocation(true)//设置是否显示定位小蓝点 + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + //定位、移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE) aMap.myLocationStyle = locationStyle aMap.isMyLocationEnabled = true aMap.mapType = AMap.MAP_TYPE_NORMAL - LocationHub.get.getLocationByAMap(requireContext(), object : LocationHub.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - "当前信号弱,无法定位".show(requireContext()) - return - } - - val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) - - //移动到指定经纬度 - val cameraPosition = CameraPosition(latLng, 16f, 0f, 0f) - val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) - aMap.animateCamera(cameraUpdate, 1500, null) - - //newInspectionModel已完成初始化,说明已经新建巡检任务,数据可以开始保存了 - if (newModel != null) { - //设置巡检起点 - if (newModel!!.startAddress.isEmpty()) { - newModel!!.startAddress = aMapLocation.address - } - - //巡检终点每次定位都覆盖,降低调用sdk频率 - newModel!!.endAddress = aMapLocation.address - - latLngs.add(latLng) - - //绘制线 - aMap.addPolyline( - PolylineOptions().addAll(latLngs).width(10f).color(Color.RED) - ) - } - } - }) - //UserName userName = SaveKeyValues.getValue(LocaleConstant.USER_NAME, "").toString() @@ -217,8 +193,11 @@ is LoadState.Success -> { LoadingDialogHub.dismiss() + //清空newModel + newModel.clearCache() + //结束任务就清空轨迹 - latLngs.clear() + latLngList.clear() aMap.clear() //按钮状态 @@ -248,16 +227,25 @@ binding.inspectNameView.text = value binding.inspectTimeView.text = startTime - newModel = NewInspectionModel( - currentTimeMillis.id(), value, - startTime, "", currentTimeMillis.timestampToDate(), - 0.0, 0.0, "", 0.0, 0.0, "", - ArrayList(), userName - ) + newModel.id = currentTimeMillis.id() + newModel.name = value + newModel.startTime = startTime + newModel.date = currentTimeMillis.timestampToDate() + newModel.user = userName //按钮状态 binding.stopInspectButton.isEnabled = true binding.addInspectionButton.isEnabled = false + + locationService?.startLocation(object : LocationHub.ILocationListener { + override fun onAMapLocationGet(aMapLocation: AMapLocation) { + drawTaskRoute(aMapLocation) + } + + override fun onAMapLocationError() { + "当前信号弱,无法定位".show(requireContext()) + } + }) } override fun onCancelClick() { @@ -284,11 +272,11 @@ requireContext().navigatePageTo( addAll( position.toString(), - newModel!!.id, - newModel!!.name, + newModel.id, + newModel.name, connectedDeviceCode, - latLngs.last.longitude.toString(), - latLngs.last.latitude.toString() + newModel.routes.last.longitude.toString(), + newModel.routes.last.latitude.toString() ) ) } @@ -296,6 +284,33 @@ } } + private fun drawTaskRoute(aMapLocation: AMapLocation) { + Log.d(kTag, "${aMapLocation.latitude}, ${aMapLocation.longitude}") + val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) + + //移动到指定经纬度 + val cameraPosition = CameraPosition(latLng, 15f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + + //stopInspectButton isEnabled,说明已经新建巡检任务,数据可以开始保存了 + if (binding.stopInspectButton.isEnabled) { + latLngList.add(latLng) + newModel.routes = latLngList + + //设置巡检起点 + if (newModel.startAddress.isNullOrEmpty()) { + newModel.startAddress = aMapLocation.address + } + + //巡检终点每次定位都覆盖,降低调用sdk频率 + newModel.endAddress = aMapLocation.address + + //绘制线 + aMap.addPolyline(PolylineOptions().addAll(newModel.routes).width(10f).color(Color.RED)) + } + } + private fun menuButtonEvent() { //结束巡检 binding.stopInspectButton.setOnClickListener { @@ -345,8 +360,6 @@ //关闭数据传送指令 bleManager.disconnectAllDevice() - latLngs.clear() - aMap.clear()//清除原来的路线 SaveKeyValues.removeKey(LocaleConstant.DEVICE_CODE) withContext(Dispatchers.Main) { binding.currentValueView.text = "--" @@ -588,44 +601,41 @@ * * 如果保存到本地,则需要设置标识位,然后finish当前页面并提示 * */ - if (newModel == null) { - "保存失败".show(requireContext()) - return - } - - // 上传巡检位置点 - for (i in 0 until latLngs.size) { - newModel!!.routes.add(latLngs[i]) + val routes = newModel.routes + for (i in 0 until routes.size) { //上传点位 routeViewModel.uploadRoutePoint( - newModel!!.id, - latLngs[i], - System.currentTimeMillis().timestampToCompleteDate() + newModel.id, routes[i], System.currentTimeMillis().timestampToCompleteDate() ) } - val first = latLngs.first - val last = latLngs.last - newModel!!.routes.calculateDistance(object : OnDistanceSearchListener { - override fun onDistanceSearched(distance: String) { - inspectionViewModel.addInspection( - id = newModel!!.id, - deviceCode = connectedDeviceCode, - name = newModel!!.name, - startTime = newModel!!.startTime, - endTime = System.currentTimeMillis().timestampToCompleteDate(), - date = newModel!!.date, - startLng = first.longitude, - startLat = first.latitude, - newModel!!.startAddress, - endLng = last.longitude, - endLat = last.latitude, - newModel!!.endAddress, - distance, - user = userName - ) - } - }) + try { + val first = routes.first + val last = routes.last + routes.calculateDistance(object : OnDistanceSearchListener { + override fun onDistanceSearched(distance: String) { + inspectionViewModel.addInspection( + id = newModel.id, + deviceCode = connectedDeviceCode, + name = newModel.name, + startTime = newModel.startTime, + endTime = System.currentTimeMillis().timestampToCompleteDate(), + date = newModel.date, + startLng = first.longitude, + startLat = first.latitude, + startAddress = newModel.startAddress, + endLng = last.longitude, + endLat = last.latitude, + endAddress = newModel.endAddress, + distance, + user = userName + ) + } + }) + } catch (e: NoSuchElementException) { + e.printStackTrace() + "无定位数据,保存任务失败".show(requireContext()) + } } /** @@ -657,10 +667,6 @@ //如果连续超过10个报警,自动生成报警事件 alarmCount++ if (alarmCount >= 10) { - if (newModel == null) { - "没有巡检任务,无法自动记录报警".show(requireContext()) - return - } generateAlarmTask(dataModel.maxPotency) } } @@ -680,12 +686,12 @@ eventViewModel.addEventTask( id = UUID.randomUUID().toString(), - inspectionId = newModel!!.id, - name = newModel!!.name, + inspectionId = newModel.id, + name = newModel.name, createTime = System.currentTimeMillis().timestampToCompleteDate(), type = "报警事件", - lng = latLngs.last.longitude, - lat = latLngs.last.latitude, + lng = newModel.routes.last.longitude, + lat = newModel.routes.last.latitude, data = maxValue, images = "", description = "自动报警记录", @@ -713,11 +719,28 @@ } //设置标题和时间 - if (newModel == null) { - return + binding.inspectNameView.text = newModel.name + binding.inspectTimeView.text = newModel.startTime + + //绑定定位服务 + Intent(requireContext(), LocationService::class.java).also { + requireContext().bindService(it, serviceConnection, Context.BIND_AUTO_CREATE) } - binding.inspectNameView.text = newModel!!.name - binding.inspectTimeView.text = newModel!!.startTime + } + + private var locationService: LocationService? = null + + private val serviceConnection = object : ServiceConnection { + override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) { + if (iBinder is LocationService.ServiceBinder) { + locationService = iBinder.getLocationService() + Log.d(kTag, "onServiceConnected: ") + } + } + + override fun onServiceDisconnected(name: ComponentName?) { + "定位服务已断开".show(requireContext()) + } } override fun onPause() { diff --git a/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.java b/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.java new file mode 100644 index 0000000..f09810f --- /dev/null +++ b/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.java @@ -0,0 +1,141 @@ +package com.casic.birmm.inspect.model; + +import com.amap.api.maps.model.LatLng; + +import java.util.LinkedList; + +public class NewInspectionModel { + private String id; + private String name; + private String startTime; + private String endTime; + private String date; + private String startLng; + private String startLat; + private String startAddress; + private String endLng; + private String endLat; + private String endAddress; + private LinkedList routes; + private String user; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + + public String getEndTime() { + return endTime; + } + + public void setEndTime(String endTime) { + this.endTime = endTime; + } + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } + + public String getStartLng() { + return startLng; + } + + public void setStartLng(String startLng) { + this.startLng = startLng; + } + + public String getStartLat() { + return startLat; + } + + public void setStartLat(String startLat) { + this.startLat = startLat; + } + + public String getStartAddress() { + return startAddress; + } + + public void setStartAddress(String startAddress) { + this.startAddress = startAddress; + } + + public String getEndLng() { + return endLng; + } + + public void setEndLng(String endLng) { + this.endLng = endLng; + } + + public String getEndLat() { + return endLat; + } + + public void setEndLat(String endLat) { + this.endLat = endLat; + } + + public String getEndAddress() { + return endAddress; + } + + public void setEndAddress(String endAddress) { + this.endAddress = endAddress; + } + + public LinkedList getRoutes() { + return routes; + } + + public void setRoutes(LinkedList routes) { + this.routes = routes; + } + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public void clearCache() { + this.id = ""; + this.name = ""; + this.startTime = ""; + this.endTime = ""; + this.date = ""; + this.startLng = ""; + this.startLat = ""; + this.startAddress = ""; + this.endLng = ""; + this.endLat = ""; + this.endAddress = ""; + this.routes.clear(); + this.user = ""; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.kt b/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.kt deleted file mode 100644 index f08334a..0000000 --- a/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.birmm.inspect.model - -import com.amap.api.maps.model.LatLng - -data class NewInspectionModel( - var id: String, - var name: String, - var startTime: String, - var endTime: String, - var date: String, - var startLng: Double, - var startLat: Double, - var startAddress: String, - var endLng: Double, - var endLat: Double, - var endAddress: String, - var routes: ArrayList, - var user: String -) \ No newline at end of file diff --git a/app/src/main/java/com/casic/birmm/inspect/single/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/birmm/inspect/single/fragment/HomePageFragment.kt index 031525e..76c7846 100644 --- a/app/src/main/java/com/casic/birmm/inspect/single/fragment/HomePageFragment.kt +++ b/app/src/main/java/com/casic/birmm/inspect/single/fragment/HomePageFragment.kt @@ -2,9 +2,14 @@ import android.bluetooth.BluetoothGatt import android.bluetooth.BluetoothGattCharacteristic +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.ServiceConnection import android.graphics.Color import android.os.Bundle import android.os.Handler +import android.os.IBinder import android.os.Message import android.os.Vibrator import android.util.Log @@ -30,6 +35,7 @@ import com.casic.birmm.inspect.extensions.toDeviceCode import com.casic.birmm.inspect.extensions.toDeviceModel import com.casic.birmm.inspect.model.NewInspectionModel +import com.casic.birmm.inspect.service.LocationService import com.casic.birmm.inspect.single.view.NewEventActivity import com.casic.birmm.inspect.utils.DataBaseManager import com.casic.birmm.inspect.utils.LocaleConstant @@ -93,12 +99,12 @@ private val kTag = "HomePageFragment" private val bleManager by lazy { BleManager.getInstance() } - private val latLngs = LinkedList() + private val newModel by lazy { NewInspectionModel() }//新建巡检数据结构模型 + private val latLngList by lazy { LinkedList() } private lateinit var aMap: AMap private lateinit var writeUuid: String private lateinit var notifyUuid: String private var vibrator: Vibrator? = null - private var newModel: NewInspectionModel? = null//新建巡检数据结构模型 private var connectedDevice: BleDevice? = null private var isGeneratingTask = false private var alarmCount = 0 @@ -136,48 +142,17 @@ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isCompassEnabled = true uiSettings.isZoomControlsEnabled = true + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 //显示定位小蓝点 val locationStyle = MyLocationStyle() - locationStyle.showMyLocation(true)//设置是否显示定位小蓝点 + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + //定位、移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE) aMap.myLocationStyle = locationStyle aMap.isMyLocationEnabled = true - aMap.mapType = AMap.MAP_TYPE_NORMAL - - LocationHub.get.getLocationByAMap(requireContext(), object : LocationHub.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - "当前信号弱,无法定位".show(requireContext()) - return - } - - val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) - - //移动到指定经纬度 - val cameraPosition = CameraPosition(latLng, 16f, 0f, 0f) - val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) - aMap.animateCamera(cameraUpdate, 1500, null) - - //newInspectionModel已完成初始化,说明已经新建巡检任务,数据可以开始保存了 - if (newModel != null) { - //设置巡检起点 - if (newModel!!.startAddress.isEmpty()) { - newModel!!.startAddress = aMapLocation.address - } - - //巡检终点每次定位都覆盖,降低调用sdk频率 - newModel!!.endAddress = aMapLocation.address - - latLngs.add(latLng) - - //绘制线 - aMap.addPolyline( - PolylineOptions().addAll(latLngs).width(10f).color(Color.RED) - ) - } - } - }) } override fun observeRequestState() { @@ -199,16 +174,25 @@ binding.inspectNameView.text = value binding.inspectTimeView.text = startTime - newModel = NewInspectionModel( - currentTimeMillis.id(), value, - startTime, "", currentTimeMillis.timestampToDate(), - 0.0, 0.0, "", 0.0, 0.0, "", - ArrayList(), "智巡宝" - ) + newModel.id = currentTimeMillis.id() + newModel.name = value + newModel.startTime = startTime + newModel.date = currentTimeMillis.timestampToDate() + newModel.user = "智巡宝" //按钮状态 binding.stopInspectButton.isEnabled = true binding.addInspectionButton.isEnabled = false + + locationService?.startLocation(object : LocationHub.ILocationListener { + override fun onAMapLocationGet(aMapLocation: AMapLocation) { + drawTaskRoute(aMapLocation) + } + + override fun onAMapLocationError() { + "当前信号弱,无法定位".show(requireContext()) + } + }) } override fun onCancelClick() { @@ -235,11 +219,11 @@ requireContext().navigatePageTo( addAll( position.toString(), - newModel!!.id, - newModel!!.name, + newModel.id, + newModel.name, connectedDeviceCode, - latLngs.last.longitude.toString(), - latLngs.last.latitude.toString() + newModel.routes.last.longitude.toString(), + newModel.routes.last.latitude.toString() ) ) } @@ -247,6 +231,33 @@ } } + private fun drawTaskRoute(aMapLocation: AMapLocation) { + Log.d(kTag, "${aMapLocation.latitude}, ${aMapLocation.longitude}") + val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) + + //移动到指定经纬度 + val cameraPosition = CameraPosition(latLng, 15f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + + //stopInspectButton isEnabled,说明已经新建巡检任务,数据可以开始保存了 + if (binding.stopInspectButton.isEnabled) { + latLngList.add(latLng) + newModel.routes = latLngList + + //设置巡检起点 + if (newModel.startAddress.isNullOrEmpty()) { + newModel.startAddress = aMapLocation.address + } + + //巡检终点每次定位都覆盖,降低调用sdk频率 + newModel.endAddress = aMapLocation.address + + //绘制线 + aMap.addPolyline(PolylineOptions().addAll(newModel.routes).width(10f).color(Color.RED)) + } + } + private fun menuButtonEvent() { //结束巡检 binding.stopInspectButton.setOnClickListener { @@ -296,8 +307,6 @@ //关闭数据传送指令 bleManager.disconnectAllDevice() - latLngs.clear() - aMap.clear()//清除原来的路线 SaveKeyValues.removeKey(LocaleConstant.DEVICE_CODE) withContext(Dispatchers.Main) { binding.currentValueView.text = "--" @@ -539,42 +548,51 @@ * * 如果保存到本地,则需要设置标识位,然后finish当前页面并提示 * */ - if (newModel == null) { - "保存失败".show(requireContext()) - return - } - LoadingDialogHub.show(requireActivity(), "数据保存中,请稍后...") + val routes = newModel.routes // 保存巡检位置点 lifecycleScope.launch(Dispatchers.Main) { withContext(Dispatchers.IO) { - for (i in 0 until latLngs.size) { - newModel!!.routes.add(latLngs[i]) - - DataBaseManager.get.addInspectionRoute(newModel!!.id, latLngs[i]) + for (i in 0 until routes.size) { + DataBaseManager.get.addInspectionRoute(newModel.id, routes[i]) } - DataBaseManager.get.addInspection( - inspectionId = newModel!!.id, - deviceCode = connectedDeviceCode, - inspectionName = newModel!!.name, - startTime = newModel!!.startTime, - endTime = System.currentTimeMillis().timestampToCompleteDate(), - date = newModel!!.date, - startLng = latLngs.first.longitude, - startLat = latLngs.first.latitude, - newModel!!.startAddress, - endLng = latLngs.last.longitude, - endLat = latLngs.last.latitude, - newModel!!.endAddress, - routes = newModel!!.routes - ) + try { + val first = routes.first + val last = routes.last + DataBaseManager.get.addInspection( + inspectionId = newModel.id, + deviceCode = connectedDeviceCode, + inspectionName = newModel.name, + startTime = newModel.startTime, + endTime = System.currentTimeMillis().timestampToCompleteDate(), + date = newModel.date, + startLng = first.longitude, + startLat = first.latitude, + startAddress = newModel.startAddress, + endLng = last.longitude, + endLat = last.latitude, + endAddress = newModel.endAddress, + routes = newModel.routes + ) + } catch (e: NoSuchElementException) { + e.printStackTrace() + withContext(Dispatchers.Main) { + "无定位数据,保存任务失败".show(requireContext()) + } + } } LoadingDialogHub.dismiss() + //清空newModel + newModel.clearCache() + + //停止定位 + locationService?.stopLocation() + //结束任务就清空轨迹 - latLngs.clear() + latLngList.clear() aMap.clear() //按钮状态 @@ -611,10 +629,6 @@ //如果连续超过10个报警,自动生成报警事件 alarmCount++ if (alarmCount >= 10) { - if (newModel == null) { - "没有巡检任务,无法自动记录报警".show(requireContext()) - return - } generateAlarmTask(dataModel.maxPotency) } } @@ -635,13 +649,13 @@ DataBaseManager.get.addEvent( taskId = UUID.randomUUID().toString(), - inspectionId = newModel!!.id, + inspectionId = newModel.id, deviceCode = connectedDeviceCode, - eventTitle = newModel!!.name, + eventTitle = newModel.name, createTime = System.currentTimeMillis().timestampToCompleteDate(), type = "报警事件", - lng = latLngs.last.longitude, - lat = latLngs.last.latitude, + lng = newModel.routes.last.longitude, + lat = newModel.routes.last.latitude, data = maxValue, images = "", description = "自动报警记录" @@ -671,11 +685,28 @@ } //设置标题和时间 - if (newModel == null) { - return + binding.inspectNameView.text = newModel.name + binding.inspectTimeView.text = newModel.startTime + + //绑定定位服务 + Intent(requireContext(), LocationService::class.java).also { + requireContext().bindService(it, serviceConnection, Context.BIND_AUTO_CREATE) } - binding.inspectNameView.text = newModel!!.name - binding.inspectTimeView.text = newModel!!.startTime + } + + private var locationService: LocationService? = null + + private val serviceConnection = object : ServiceConnection { + override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) { + if (iBinder is LocationService.ServiceBinder) { + locationService = iBinder.getLocationService() + Log.d(kTag, "onServiceConnected: ") + } + } + + override fun onServiceDisconnected(name: ComponentName?) { + "定位服务已断开".show(requireContext()) + } } override fun onPause() { diff --git a/app/build.gradle b/app/build.gradle index 9d0f82e..feb5ca9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -20,8 +20,8 @@ applicationId "com.casic.birmm.inspect" minSdkVersion 23 targetSdkVersion 33 - versionCode 1071 - versionName "1.0.7.1" + versionCode 1072 + versionName "1.0.7.2" } buildTypes { diff --git a/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt b/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt index 30b8f28..12c92e6 100644 --- a/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt @@ -1,12 +1,5 @@ package com.casic.birmm.inspect.extensions -import com.amap.api.maps.model.LatLng -import com.amap.api.services.core.LatLonPoint -import com.amap.api.services.route.DistanceSearch -import com.casic.birmm.inspect.base.BaseApplication -import com.casic.birmm.inspect.callback.OnDistanceSearchListener -import java.text.DecimalFormat - /** * ArrayList扩展方法 */ @@ -32,39 +25,4 @@ result.add(it) } return result -} - -private val distanceSearch by lazy { DistanceSearch(BaseApplication.get()) } -private val distanceQuery by lazy { DistanceSearch.DistanceQuery() } -private val decimalFormat by lazy { DecimalFormat("#.##") } - -fun ArrayList.calculateDistance(listener: OnDistanceSearchListener) { - if (this.isEmpty()) { - listener.onDistanceSearched("0.00") - } - - val last = this.last() - val dest = LatLonPoint(last.latitude, last.longitude) - - //去掉最后一个点 - this.removeLast() - val latLonPoints: ArrayList = ArrayList() - this.forEach { - latLonPoints.add(LatLonPoint(it.latitude, it.longitude)) - } - - distanceQuery.origins = latLonPoints - distanceQuery.destination = dest - distanceQuery.type = DistanceSearch.TYPE_WALK_DISTANCE - distanceSearch.calculateRouteDistanceAsyn(distanceQuery) - distanceSearch.setDistanceSearchListener { distanceResult, errorCode -> - if (errorCode == 1000) { - //DistanceResult返回的是单位是米 - val temp = distanceResult.distanceResults[0].distance - val distance = temp / 1000 - listener.onDistanceSearched(decimalFormat.format(distance)) - } else { - listener.onDistanceSearched("0.00") - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt index d5b1bc0..13b752f 100644 --- a/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt +++ b/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt @@ -2,9 +2,14 @@ import android.bluetooth.BluetoothGatt import android.bluetooth.BluetoothGattCharacteristic +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.ServiceConnection import android.graphics.Color import android.os.Bundle import android.os.Handler +import android.os.IBinder import android.os.Message import android.os.Vibrator import android.util.Log @@ -33,6 +38,7 @@ import com.casic.birmm.inspect.extensions.toDeviceCode import com.casic.birmm.inspect.extensions.toDeviceModel import com.casic.birmm.inspect.model.NewInspectionModel +import com.casic.birmm.inspect.service.LocationService import com.casic.birmm.inspect.utils.LocaleConstant import com.casic.birmm.inspect.utils.LocationHub import com.casic.birmm.inspect.utils.SoundPoolHelper @@ -99,7 +105,8 @@ private val kTag = "HomePageFragment" private val bleManager by lazy { BleManager.getInstance() } - private val latLngs = LinkedList() + private val newModel by lazy { NewInspectionModel() }//新建巡检数据结构模型 + private val latLngList by lazy { LinkedList() } private lateinit var userName: String private lateinit var eventViewModel: EventViewModel private lateinit var inspectionViewModel: InspectionViewModel @@ -108,7 +115,6 @@ private lateinit var writeUuid: String private lateinit var notifyUuid: String private var vibrator: Vibrator? = null - private var newModel: NewInspectionModel? = null//新建巡检数据结构模型 private var connectedDevice: BleDevice? = null private var isGeneratingTask = false private var alarmCount = 0 @@ -147,49 +153,19 @@ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isCompassEnabled = true uiSettings.isZoomControlsEnabled = true + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 //显示定位小蓝点 val locationStyle = MyLocationStyle() - locationStyle.showMyLocation(true)//设置是否显示定位小蓝点 + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + //定位、移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE) aMap.myLocationStyle = locationStyle aMap.isMyLocationEnabled = true aMap.mapType = AMap.MAP_TYPE_NORMAL - LocationHub.get.getLocationByAMap(requireContext(), object : LocationHub.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - "当前信号弱,无法定位".show(requireContext()) - return - } - - val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) - - //移动到指定经纬度 - val cameraPosition = CameraPosition(latLng, 16f, 0f, 0f) - val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) - aMap.animateCamera(cameraUpdate, 1500, null) - - //newInspectionModel已完成初始化,说明已经新建巡检任务,数据可以开始保存了 - if (newModel != null) { - //设置巡检起点 - if (newModel!!.startAddress.isEmpty()) { - newModel!!.startAddress = aMapLocation.address - } - - //巡检终点每次定位都覆盖,降低调用sdk频率 - newModel!!.endAddress = aMapLocation.address - - latLngs.add(latLng) - - //绘制线 - aMap.addPolyline( - PolylineOptions().addAll(latLngs).width(10f).color(Color.RED) - ) - } - } - }) - //UserName userName = SaveKeyValues.getValue(LocaleConstant.USER_NAME, "").toString() @@ -217,8 +193,11 @@ is LoadState.Success -> { LoadingDialogHub.dismiss() + //清空newModel + newModel.clearCache() + //结束任务就清空轨迹 - latLngs.clear() + latLngList.clear() aMap.clear() //按钮状态 @@ -248,16 +227,25 @@ binding.inspectNameView.text = value binding.inspectTimeView.text = startTime - newModel = NewInspectionModel( - currentTimeMillis.id(), value, - startTime, "", currentTimeMillis.timestampToDate(), - 0.0, 0.0, "", 0.0, 0.0, "", - ArrayList(), userName - ) + newModel.id = currentTimeMillis.id() + newModel.name = value + newModel.startTime = startTime + newModel.date = currentTimeMillis.timestampToDate() + newModel.user = userName //按钮状态 binding.stopInspectButton.isEnabled = true binding.addInspectionButton.isEnabled = false + + locationService?.startLocation(object : LocationHub.ILocationListener { + override fun onAMapLocationGet(aMapLocation: AMapLocation) { + drawTaskRoute(aMapLocation) + } + + override fun onAMapLocationError() { + "当前信号弱,无法定位".show(requireContext()) + } + }) } override fun onCancelClick() { @@ -284,11 +272,11 @@ requireContext().navigatePageTo( addAll( position.toString(), - newModel!!.id, - newModel!!.name, + newModel.id, + newModel.name, connectedDeviceCode, - latLngs.last.longitude.toString(), - latLngs.last.latitude.toString() + newModel.routes.last.longitude.toString(), + newModel.routes.last.latitude.toString() ) ) } @@ -296,6 +284,33 @@ } } + private fun drawTaskRoute(aMapLocation: AMapLocation) { + Log.d(kTag, "${aMapLocation.latitude}, ${aMapLocation.longitude}") + val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) + + //移动到指定经纬度 + val cameraPosition = CameraPosition(latLng, 15f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + + //stopInspectButton isEnabled,说明已经新建巡检任务,数据可以开始保存了 + if (binding.stopInspectButton.isEnabled) { + latLngList.add(latLng) + newModel.routes = latLngList + + //设置巡检起点 + if (newModel.startAddress.isNullOrEmpty()) { + newModel.startAddress = aMapLocation.address + } + + //巡检终点每次定位都覆盖,降低调用sdk频率 + newModel.endAddress = aMapLocation.address + + //绘制线 + aMap.addPolyline(PolylineOptions().addAll(newModel.routes).width(10f).color(Color.RED)) + } + } + private fun menuButtonEvent() { //结束巡检 binding.stopInspectButton.setOnClickListener { @@ -345,8 +360,6 @@ //关闭数据传送指令 bleManager.disconnectAllDevice() - latLngs.clear() - aMap.clear()//清除原来的路线 SaveKeyValues.removeKey(LocaleConstant.DEVICE_CODE) withContext(Dispatchers.Main) { binding.currentValueView.text = "--" @@ -588,44 +601,41 @@ * * 如果保存到本地,则需要设置标识位,然后finish当前页面并提示 * */ - if (newModel == null) { - "保存失败".show(requireContext()) - return - } - - // 上传巡检位置点 - for (i in 0 until latLngs.size) { - newModel!!.routes.add(latLngs[i]) + val routes = newModel.routes + for (i in 0 until routes.size) { //上传点位 routeViewModel.uploadRoutePoint( - newModel!!.id, - latLngs[i], - System.currentTimeMillis().timestampToCompleteDate() + newModel.id, routes[i], System.currentTimeMillis().timestampToCompleteDate() ) } - val first = latLngs.first - val last = latLngs.last - newModel!!.routes.calculateDistance(object : OnDistanceSearchListener { - override fun onDistanceSearched(distance: String) { - inspectionViewModel.addInspection( - id = newModel!!.id, - deviceCode = connectedDeviceCode, - name = newModel!!.name, - startTime = newModel!!.startTime, - endTime = System.currentTimeMillis().timestampToCompleteDate(), - date = newModel!!.date, - startLng = first.longitude, - startLat = first.latitude, - newModel!!.startAddress, - endLng = last.longitude, - endLat = last.latitude, - newModel!!.endAddress, - distance, - user = userName - ) - } - }) + try { + val first = routes.first + val last = routes.last + routes.calculateDistance(object : OnDistanceSearchListener { + override fun onDistanceSearched(distance: String) { + inspectionViewModel.addInspection( + id = newModel.id, + deviceCode = connectedDeviceCode, + name = newModel.name, + startTime = newModel.startTime, + endTime = System.currentTimeMillis().timestampToCompleteDate(), + date = newModel.date, + startLng = first.longitude, + startLat = first.latitude, + startAddress = newModel.startAddress, + endLng = last.longitude, + endLat = last.latitude, + endAddress = newModel.endAddress, + distance, + user = userName + ) + } + }) + } catch (e: NoSuchElementException) { + e.printStackTrace() + "无定位数据,保存任务失败".show(requireContext()) + } } /** @@ -657,10 +667,6 @@ //如果连续超过10个报警,自动生成报警事件 alarmCount++ if (alarmCount >= 10) { - if (newModel == null) { - "没有巡检任务,无法自动记录报警".show(requireContext()) - return - } generateAlarmTask(dataModel.maxPotency) } } @@ -680,12 +686,12 @@ eventViewModel.addEventTask( id = UUID.randomUUID().toString(), - inspectionId = newModel!!.id, - name = newModel!!.name, + inspectionId = newModel.id, + name = newModel.name, createTime = System.currentTimeMillis().timestampToCompleteDate(), type = "报警事件", - lng = latLngs.last.longitude, - lat = latLngs.last.latitude, + lng = newModel.routes.last.longitude, + lat = newModel.routes.last.latitude, data = maxValue, images = "", description = "自动报警记录", @@ -713,11 +719,28 @@ } //设置标题和时间 - if (newModel == null) { - return + binding.inspectNameView.text = newModel.name + binding.inspectTimeView.text = newModel.startTime + + //绑定定位服务 + Intent(requireContext(), LocationService::class.java).also { + requireContext().bindService(it, serviceConnection, Context.BIND_AUTO_CREATE) } - binding.inspectNameView.text = newModel!!.name - binding.inspectTimeView.text = newModel!!.startTime + } + + private var locationService: LocationService? = null + + private val serviceConnection = object : ServiceConnection { + override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) { + if (iBinder is LocationService.ServiceBinder) { + locationService = iBinder.getLocationService() + Log.d(kTag, "onServiceConnected: ") + } + } + + override fun onServiceDisconnected(name: ComponentName?) { + "定位服务已断开".show(requireContext()) + } } override fun onPause() { diff --git a/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.java b/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.java new file mode 100644 index 0000000..f09810f --- /dev/null +++ b/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.java @@ -0,0 +1,141 @@ +package com.casic.birmm.inspect.model; + +import com.amap.api.maps.model.LatLng; + +import java.util.LinkedList; + +public class NewInspectionModel { + private String id; + private String name; + private String startTime; + private String endTime; + private String date; + private String startLng; + private String startLat; + private String startAddress; + private String endLng; + private String endLat; + private String endAddress; + private LinkedList routes; + private String user; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + + public String getEndTime() { + return endTime; + } + + public void setEndTime(String endTime) { + this.endTime = endTime; + } + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } + + public String getStartLng() { + return startLng; + } + + public void setStartLng(String startLng) { + this.startLng = startLng; + } + + public String getStartLat() { + return startLat; + } + + public void setStartLat(String startLat) { + this.startLat = startLat; + } + + public String getStartAddress() { + return startAddress; + } + + public void setStartAddress(String startAddress) { + this.startAddress = startAddress; + } + + public String getEndLng() { + return endLng; + } + + public void setEndLng(String endLng) { + this.endLng = endLng; + } + + public String getEndLat() { + return endLat; + } + + public void setEndLat(String endLat) { + this.endLat = endLat; + } + + public String getEndAddress() { + return endAddress; + } + + public void setEndAddress(String endAddress) { + this.endAddress = endAddress; + } + + public LinkedList getRoutes() { + return routes; + } + + public void setRoutes(LinkedList routes) { + this.routes = routes; + } + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public void clearCache() { + this.id = ""; + this.name = ""; + this.startTime = ""; + this.endTime = ""; + this.date = ""; + this.startLng = ""; + this.startLat = ""; + this.startAddress = ""; + this.endLng = ""; + this.endLat = ""; + this.endAddress = ""; + this.routes.clear(); + this.user = ""; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.kt b/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.kt deleted file mode 100644 index f08334a..0000000 --- a/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.birmm.inspect.model - -import com.amap.api.maps.model.LatLng - -data class NewInspectionModel( - var id: String, - var name: String, - var startTime: String, - var endTime: String, - var date: String, - var startLng: Double, - var startLat: Double, - var startAddress: String, - var endLng: Double, - var endLat: Double, - var endAddress: String, - var routes: ArrayList, - var user: String -) \ No newline at end of file diff --git a/app/src/main/java/com/casic/birmm/inspect/single/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/birmm/inspect/single/fragment/HomePageFragment.kt index 031525e..76c7846 100644 --- a/app/src/main/java/com/casic/birmm/inspect/single/fragment/HomePageFragment.kt +++ b/app/src/main/java/com/casic/birmm/inspect/single/fragment/HomePageFragment.kt @@ -2,9 +2,14 @@ import android.bluetooth.BluetoothGatt import android.bluetooth.BluetoothGattCharacteristic +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.ServiceConnection import android.graphics.Color import android.os.Bundle import android.os.Handler +import android.os.IBinder import android.os.Message import android.os.Vibrator import android.util.Log @@ -30,6 +35,7 @@ import com.casic.birmm.inspect.extensions.toDeviceCode import com.casic.birmm.inspect.extensions.toDeviceModel import com.casic.birmm.inspect.model.NewInspectionModel +import com.casic.birmm.inspect.service.LocationService import com.casic.birmm.inspect.single.view.NewEventActivity import com.casic.birmm.inspect.utils.DataBaseManager import com.casic.birmm.inspect.utils.LocaleConstant @@ -93,12 +99,12 @@ private val kTag = "HomePageFragment" private val bleManager by lazy { BleManager.getInstance() } - private val latLngs = LinkedList() + private val newModel by lazy { NewInspectionModel() }//新建巡检数据结构模型 + private val latLngList by lazy { LinkedList() } private lateinit var aMap: AMap private lateinit var writeUuid: String private lateinit var notifyUuid: String private var vibrator: Vibrator? = null - private var newModel: NewInspectionModel? = null//新建巡检数据结构模型 private var connectedDevice: BleDevice? = null private var isGeneratingTask = false private var alarmCount = 0 @@ -136,48 +142,17 @@ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isCompassEnabled = true uiSettings.isZoomControlsEnabled = true + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 //显示定位小蓝点 val locationStyle = MyLocationStyle() - locationStyle.showMyLocation(true)//设置是否显示定位小蓝点 + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + //定位、移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE) aMap.myLocationStyle = locationStyle aMap.isMyLocationEnabled = true - aMap.mapType = AMap.MAP_TYPE_NORMAL - - LocationHub.get.getLocationByAMap(requireContext(), object : LocationHub.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - "当前信号弱,无法定位".show(requireContext()) - return - } - - val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) - - //移动到指定经纬度 - val cameraPosition = CameraPosition(latLng, 16f, 0f, 0f) - val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) - aMap.animateCamera(cameraUpdate, 1500, null) - - //newInspectionModel已完成初始化,说明已经新建巡检任务,数据可以开始保存了 - if (newModel != null) { - //设置巡检起点 - if (newModel!!.startAddress.isEmpty()) { - newModel!!.startAddress = aMapLocation.address - } - - //巡检终点每次定位都覆盖,降低调用sdk频率 - newModel!!.endAddress = aMapLocation.address - - latLngs.add(latLng) - - //绘制线 - aMap.addPolyline( - PolylineOptions().addAll(latLngs).width(10f).color(Color.RED) - ) - } - } - }) } override fun observeRequestState() { @@ -199,16 +174,25 @@ binding.inspectNameView.text = value binding.inspectTimeView.text = startTime - newModel = NewInspectionModel( - currentTimeMillis.id(), value, - startTime, "", currentTimeMillis.timestampToDate(), - 0.0, 0.0, "", 0.0, 0.0, "", - ArrayList(), "智巡宝" - ) + newModel.id = currentTimeMillis.id() + newModel.name = value + newModel.startTime = startTime + newModel.date = currentTimeMillis.timestampToDate() + newModel.user = "智巡宝" //按钮状态 binding.stopInspectButton.isEnabled = true binding.addInspectionButton.isEnabled = false + + locationService?.startLocation(object : LocationHub.ILocationListener { + override fun onAMapLocationGet(aMapLocation: AMapLocation) { + drawTaskRoute(aMapLocation) + } + + override fun onAMapLocationError() { + "当前信号弱,无法定位".show(requireContext()) + } + }) } override fun onCancelClick() { @@ -235,11 +219,11 @@ requireContext().navigatePageTo( addAll( position.toString(), - newModel!!.id, - newModel!!.name, + newModel.id, + newModel.name, connectedDeviceCode, - latLngs.last.longitude.toString(), - latLngs.last.latitude.toString() + newModel.routes.last.longitude.toString(), + newModel.routes.last.latitude.toString() ) ) } @@ -247,6 +231,33 @@ } } + private fun drawTaskRoute(aMapLocation: AMapLocation) { + Log.d(kTag, "${aMapLocation.latitude}, ${aMapLocation.longitude}") + val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) + + //移动到指定经纬度 + val cameraPosition = CameraPosition(latLng, 15f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + + //stopInspectButton isEnabled,说明已经新建巡检任务,数据可以开始保存了 + if (binding.stopInspectButton.isEnabled) { + latLngList.add(latLng) + newModel.routes = latLngList + + //设置巡检起点 + if (newModel.startAddress.isNullOrEmpty()) { + newModel.startAddress = aMapLocation.address + } + + //巡检终点每次定位都覆盖,降低调用sdk频率 + newModel.endAddress = aMapLocation.address + + //绘制线 + aMap.addPolyline(PolylineOptions().addAll(newModel.routes).width(10f).color(Color.RED)) + } + } + private fun menuButtonEvent() { //结束巡检 binding.stopInspectButton.setOnClickListener { @@ -296,8 +307,6 @@ //关闭数据传送指令 bleManager.disconnectAllDevice() - latLngs.clear() - aMap.clear()//清除原来的路线 SaveKeyValues.removeKey(LocaleConstant.DEVICE_CODE) withContext(Dispatchers.Main) { binding.currentValueView.text = "--" @@ -539,42 +548,51 @@ * * 如果保存到本地,则需要设置标识位,然后finish当前页面并提示 * */ - if (newModel == null) { - "保存失败".show(requireContext()) - return - } - LoadingDialogHub.show(requireActivity(), "数据保存中,请稍后...") + val routes = newModel.routes // 保存巡检位置点 lifecycleScope.launch(Dispatchers.Main) { withContext(Dispatchers.IO) { - for (i in 0 until latLngs.size) { - newModel!!.routes.add(latLngs[i]) - - DataBaseManager.get.addInspectionRoute(newModel!!.id, latLngs[i]) + for (i in 0 until routes.size) { + DataBaseManager.get.addInspectionRoute(newModel.id, routes[i]) } - DataBaseManager.get.addInspection( - inspectionId = newModel!!.id, - deviceCode = connectedDeviceCode, - inspectionName = newModel!!.name, - startTime = newModel!!.startTime, - endTime = System.currentTimeMillis().timestampToCompleteDate(), - date = newModel!!.date, - startLng = latLngs.first.longitude, - startLat = latLngs.first.latitude, - newModel!!.startAddress, - endLng = latLngs.last.longitude, - endLat = latLngs.last.latitude, - newModel!!.endAddress, - routes = newModel!!.routes - ) + try { + val first = routes.first + val last = routes.last + DataBaseManager.get.addInspection( + inspectionId = newModel.id, + deviceCode = connectedDeviceCode, + inspectionName = newModel.name, + startTime = newModel.startTime, + endTime = System.currentTimeMillis().timestampToCompleteDate(), + date = newModel.date, + startLng = first.longitude, + startLat = first.latitude, + startAddress = newModel.startAddress, + endLng = last.longitude, + endLat = last.latitude, + endAddress = newModel.endAddress, + routes = newModel.routes + ) + } catch (e: NoSuchElementException) { + e.printStackTrace() + withContext(Dispatchers.Main) { + "无定位数据,保存任务失败".show(requireContext()) + } + } } LoadingDialogHub.dismiss() + //清空newModel + newModel.clearCache() + + //停止定位 + locationService?.stopLocation() + //结束任务就清空轨迹 - latLngs.clear() + latLngList.clear() aMap.clear() //按钮状态 @@ -611,10 +629,6 @@ //如果连续超过10个报警,自动生成报警事件 alarmCount++ if (alarmCount >= 10) { - if (newModel == null) { - "没有巡检任务,无法自动记录报警".show(requireContext()) - return - } generateAlarmTask(dataModel.maxPotency) } } @@ -635,13 +649,13 @@ DataBaseManager.get.addEvent( taskId = UUID.randomUUID().toString(), - inspectionId = newModel!!.id, + inspectionId = newModel.id, deviceCode = connectedDeviceCode, - eventTitle = newModel!!.name, + eventTitle = newModel.name, createTime = System.currentTimeMillis().timestampToCompleteDate(), type = "报警事件", - lng = latLngs.last.longitude, - lat = latLngs.last.latitude, + lng = newModel.routes.last.longitude, + lat = newModel.routes.last.latitude, data = maxValue, images = "", description = "自动报警记录" @@ -671,11 +685,28 @@ } //设置标题和时间 - if (newModel == null) { - return + binding.inspectNameView.text = newModel.name + binding.inspectTimeView.text = newModel.startTime + + //绑定定位服务 + Intent(requireContext(), LocationService::class.java).also { + requireContext().bindService(it, serviceConnection, Context.BIND_AUTO_CREATE) } - binding.inspectNameView.text = newModel!!.name - binding.inspectTimeView.text = newModel!!.startTime + } + + private var locationService: LocationService? = null + + private val serviceConnection = object : ServiceConnection { + override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) { + if (iBinder is LocationService.ServiceBinder) { + locationService = iBinder.getLocationService() + Log.d(kTag, "onServiceConnected: ") + } + } + + override fun onServiceDisconnected(name: ComponentName?) { + "定位服务已断开".show(requireContext()) + } } override fun onPause() { diff --git a/app/src/main/java/com/casic/birmm/inspect/utils/DataBaseManager.kt b/app/src/main/java/com/casic/birmm/inspect/utils/DataBaseManager.kt index 3a2cac1..268f37b 100644 --- a/app/src/main/java/com/casic/birmm/inspect/utils/DataBaseManager.kt +++ b/app/src/main/java/com/casic/birmm/inspect/utils/DataBaseManager.kt @@ -12,6 +12,7 @@ import com.casic.birmm.inspect.greendao.TaskEventLocalBeanDao import com.casic.birmm.inspect.single.fragment.QueryEventFragment import com.casic.birmm.inspect.single.fragment.QueryInspectionFragment +import java.util.LinkedList class DataBaseManager private constructor() { @@ -44,7 +45,7 @@ endLng: Double, endLat: Double, endAddress: String, - routes: ArrayList + routes: LinkedList ) { val bean = InspectionLocalBean() bean.inspectionId = inspectionId diff --git a/app/build.gradle b/app/build.gradle index 9d0f82e..feb5ca9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -20,8 +20,8 @@ applicationId "com.casic.birmm.inspect" minSdkVersion 23 targetSdkVersion 33 - versionCode 1071 - versionName "1.0.7.1" + versionCode 1072 + versionName "1.0.7.2" } buildTypes { diff --git a/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt b/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt index 30b8f28..12c92e6 100644 --- a/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt @@ -1,12 +1,5 @@ package com.casic.birmm.inspect.extensions -import com.amap.api.maps.model.LatLng -import com.amap.api.services.core.LatLonPoint -import com.amap.api.services.route.DistanceSearch -import com.casic.birmm.inspect.base.BaseApplication -import com.casic.birmm.inspect.callback.OnDistanceSearchListener -import java.text.DecimalFormat - /** * ArrayList扩展方法 */ @@ -32,39 +25,4 @@ result.add(it) } return result -} - -private val distanceSearch by lazy { DistanceSearch(BaseApplication.get()) } -private val distanceQuery by lazy { DistanceSearch.DistanceQuery() } -private val decimalFormat by lazy { DecimalFormat("#.##") } - -fun ArrayList.calculateDistance(listener: OnDistanceSearchListener) { - if (this.isEmpty()) { - listener.onDistanceSearched("0.00") - } - - val last = this.last() - val dest = LatLonPoint(last.latitude, last.longitude) - - //去掉最后一个点 - this.removeLast() - val latLonPoints: ArrayList = ArrayList() - this.forEach { - latLonPoints.add(LatLonPoint(it.latitude, it.longitude)) - } - - distanceQuery.origins = latLonPoints - distanceQuery.destination = dest - distanceQuery.type = DistanceSearch.TYPE_WALK_DISTANCE - distanceSearch.calculateRouteDistanceAsyn(distanceQuery) - distanceSearch.setDistanceSearchListener { distanceResult, errorCode -> - if (errorCode == 1000) { - //DistanceResult返回的是单位是米 - val temp = distanceResult.distanceResults[0].distance - val distance = temp / 1000 - listener.onDistanceSearched(decimalFormat.format(distance)) - } else { - listener.onDistanceSearched("0.00") - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt index d5b1bc0..13b752f 100644 --- a/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt +++ b/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt @@ -2,9 +2,14 @@ import android.bluetooth.BluetoothGatt import android.bluetooth.BluetoothGattCharacteristic +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.ServiceConnection import android.graphics.Color import android.os.Bundle import android.os.Handler +import android.os.IBinder import android.os.Message import android.os.Vibrator import android.util.Log @@ -33,6 +38,7 @@ import com.casic.birmm.inspect.extensions.toDeviceCode import com.casic.birmm.inspect.extensions.toDeviceModel import com.casic.birmm.inspect.model.NewInspectionModel +import com.casic.birmm.inspect.service.LocationService import com.casic.birmm.inspect.utils.LocaleConstant import com.casic.birmm.inspect.utils.LocationHub import com.casic.birmm.inspect.utils.SoundPoolHelper @@ -99,7 +105,8 @@ private val kTag = "HomePageFragment" private val bleManager by lazy { BleManager.getInstance() } - private val latLngs = LinkedList() + private val newModel by lazy { NewInspectionModel() }//新建巡检数据结构模型 + private val latLngList by lazy { LinkedList() } private lateinit var userName: String private lateinit var eventViewModel: EventViewModel private lateinit var inspectionViewModel: InspectionViewModel @@ -108,7 +115,6 @@ private lateinit var writeUuid: String private lateinit var notifyUuid: String private var vibrator: Vibrator? = null - private var newModel: NewInspectionModel? = null//新建巡检数据结构模型 private var connectedDevice: BleDevice? = null private var isGeneratingTask = false private var alarmCount = 0 @@ -147,49 +153,19 @@ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isCompassEnabled = true uiSettings.isZoomControlsEnabled = true + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 //显示定位小蓝点 val locationStyle = MyLocationStyle() - locationStyle.showMyLocation(true)//设置是否显示定位小蓝点 + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + //定位、移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE) aMap.myLocationStyle = locationStyle aMap.isMyLocationEnabled = true aMap.mapType = AMap.MAP_TYPE_NORMAL - LocationHub.get.getLocationByAMap(requireContext(), object : LocationHub.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - "当前信号弱,无法定位".show(requireContext()) - return - } - - val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) - - //移动到指定经纬度 - val cameraPosition = CameraPosition(latLng, 16f, 0f, 0f) - val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) - aMap.animateCamera(cameraUpdate, 1500, null) - - //newInspectionModel已完成初始化,说明已经新建巡检任务,数据可以开始保存了 - if (newModel != null) { - //设置巡检起点 - if (newModel!!.startAddress.isEmpty()) { - newModel!!.startAddress = aMapLocation.address - } - - //巡检终点每次定位都覆盖,降低调用sdk频率 - newModel!!.endAddress = aMapLocation.address - - latLngs.add(latLng) - - //绘制线 - aMap.addPolyline( - PolylineOptions().addAll(latLngs).width(10f).color(Color.RED) - ) - } - } - }) - //UserName userName = SaveKeyValues.getValue(LocaleConstant.USER_NAME, "").toString() @@ -217,8 +193,11 @@ is LoadState.Success -> { LoadingDialogHub.dismiss() + //清空newModel + newModel.clearCache() + //结束任务就清空轨迹 - latLngs.clear() + latLngList.clear() aMap.clear() //按钮状态 @@ -248,16 +227,25 @@ binding.inspectNameView.text = value binding.inspectTimeView.text = startTime - newModel = NewInspectionModel( - currentTimeMillis.id(), value, - startTime, "", currentTimeMillis.timestampToDate(), - 0.0, 0.0, "", 0.0, 0.0, "", - ArrayList(), userName - ) + newModel.id = currentTimeMillis.id() + newModel.name = value + newModel.startTime = startTime + newModel.date = currentTimeMillis.timestampToDate() + newModel.user = userName //按钮状态 binding.stopInspectButton.isEnabled = true binding.addInspectionButton.isEnabled = false + + locationService?.startLocation(object : LocationHub.ILocationListener { + override fun onAMapLocationGet(aMapLocation: AMapLocation) { + drawTaskRoute(aMapLocation) + } + + override fun onAMapLocationError() { + "当前信号弱,无法定位".show(requireContext()) + } + }) } override fun onCancelClick() { @@ -284,11 +272,11 @@ requireContext().navigatePageTo( addAll( position.toString(), - newModel!!.id, - newModel!!.name, + newModel.id, + newModel.name, connectedDeviceCode, - latLngs.last.longitude.toString(), - latLngs.last.latitude.toString() + newModel.routes.last.longitude.toString(), + newModel.routes.last.latitude.toString() ) ) } @@ -296,6 +284,33 @@ } } + private fun drawTaskRoute(aMapLocation: AMapLocation) { + Log.d(kTag, "${aMapLocation.latitude}, ${aMapLocation.longitude}") + val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) + + //移动到指定经纬度 + val cameraPosition = CameraPosition(latLng, 15f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + + //stopInspectButton isEnabled,说明已经新建巡检任务,数据可以开始保存了 + if (binding.stopInspectButton.isEnabled) { + latLngList.add(latLng) + newModel.routes = latLngList + + //设置巡检起点 + if (newModel.startAddress.isNullOrEmpty()) { + newModel.startAddress = aMapLocation.address + } + + //巡检终点每次定位都覆盖,降低调用sdk频率 + newModel.endAddress = aMapLocation.address + + //绘制线 + aMap.addPolyline(PolylineOptions().addAll(newModel.routes).width(10f).color(Color.RED)) + } + } + private fun menuButtonEvent() { //结束巡检 binding.stopInspectButton.setOnClickListener { @@ -345,8 +360,6 @@ //关闭数据传送指令 bleManager.disconnectAllDevice() - latLngs.clear() - aMap.clear()//清除原来的路线 SaveKeyValues.removeKey(LocaleConstant.DEVICE_CODE) withContext(Dispatchers.Main) { binding.currentValueView.text = "--" @@ -588,44 +601,41 @@ * * 如果保存到本地,则需要设置标识位,然后finish当前页面并提示 * */ - if (newModel == null) { - "保存失败".show(requireContext()) - return - } - - // 上传巡检位置点 - for (i in 0 until latLngs.size) { - newModel!!.routes.add(latLngs[i]) + val routes = newModel.routes + for (i in 0 until routes.size) { //上传点位 routeViewModel.uploadRoutePoint( - newModel!!.id, - latLngs[i], - System.currentTimeMillis().timestampToCompleteDate() + newModel.id, routes[i], System.currentTimeMillis().timestampToCompleteDate() ) } - val first = latLngs.first - val last = latLngs.last - newModel!!.routes.calculateDistance(object : OnDistanceSearchListener { - override fun onDistanceSearched(distance: String) { - inspectionViewModel.addInspection( - id = newModel!!.id, - deviceCode = connectedDeviceCode, - name = newModel!!.name, - startTime = newModel!!.startTime, - endTime = System.currentTimeMillis().timestampToCompleteDate(), - date = newModel!!.date, - startLng = first.longitude, - startLat = first.latitude, - newModel!!.startAddress, - endLng = last.longitude, - endLat = last.latitude, - newModel!!.endAddress, - distance, - user = userName - ) - } - }) + try { + val first = routes.first + val last = routes.last + routes.calculateDistance(object : OnDistanceSearchListener { + override fun onDistanceSearched(distance: String) { + inspectionViewModel.addInspection( + id = newModel.id, + deviceCode = connectedDeviceCode, + name = newModel.name, + startTime = newModel.startTime, + endTime = System.currentTimeMillis().timestampToCompleteDate(), + date = newModel.date, + startLng = first.longitude, + startLat = first.latitude, + startAddress = newModel.startAddress, + endLng = last.longitude, + endLat = last.latitude, + endAddress = newModel.endAddress, + distance, + user = userName + ) + } + }) + } catch (e: NoSuchElementException) { + e.printStackTrace() + "无定位数据,保存任务失败".show(requireContext()) + } } /** @@ -657,10 +667,6 @@ //如果连续超过10个报警,自动生成报警事件 alarmCount++ if (alarmCount >= 10) { - if (newModel == null) { - "没有巡检任务,无法自动记录报警".show(requireContext()) - return - } generateAlarmTask(dataModel.maxPotency) } } @@ -680,12 +686,12 @@ eventViewModel.addEventTask( id = UUID.randomUUID().toString(), - inspectionId = newModel!!.id, - name = newModel!!.name, + inspectionId = newModel.id, + name = newModel.name, createTime = System.currentTimeMillis().timestampToCompleteDate(), type = "报警事件", - lng = latLngs.last.longitude, - lat = latLngs.last.latitude, + lng = newModel.routes.last.longitude, + lat = newModel.routes.last.latitude, data = maxValue, images = "", description = "自动报警记录", @@ -713,11 +719,28 @@ } //设置标题和时间 - if (newModel == null) { - return + binding.inspectNameView.text = newModel.name + binding.inspectTimeView.text = newModel.startTime + + //绑定定位服务 + Intent(requireContext(), LocationService::class.java).also { + requireContext().bindService(it, serviceConnection, Context.BIND_AUTO_CREATE) } - binding.inspectNameView.text = newModel!!.name - binding.inspectTimeView.text = newModel!!.startTime + } + + private var locationService: LocationService? = null + + private val serviceConnection = object : ServiceConnection { + override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) { + if (iBinder is LocationService.ServiceBinder) { + locationService = iBinder.getLocationService() + Log.d(kTag, "onServiceConnected: ") + } + } + + override fun onServiceDisconnected(name: ComponentName?) { + "定位服务已断开".show(requireContext()) + } } override fun onPause() { diff --git a/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.java b/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.java new file mode 100644 index 0000000..f09810f --- /dev/null +++ b/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.java @@ -0,0 +1,141 @@ +package com.casic.birmm.inspect.model; + +import com.amap.api.maps.model.LatLng; + +import java.util.LinkedList; + +public class NewInspectionModel { + private String id; + private String name; + private String startTime; + private String endTime; + private String date; + private String startLng; + private String startLat; + private String startAddress; + private String endLng; + private String endLat; + private String endAddress; + private LinkedList routes; + private String user; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + + public String getEndTime() { + return endTime; + } + + public void setEndTime(String endTime) { + this.endTime = endTime; + } + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } + + public String getStartLng() { + return startLng; + } + + public void setStartLng(String startLng) { + this.startLng = startLng; + } + + public String getStartLat() { + return startLat; + } + + public void setStartLat(String startLat) { + this.startLat = startLat; + } + + public String getStartAddress() { + return startAddress; + } + + public void setStartAddress(String startAddress) { + this.startAddress = startAddress; + } + + public String getEndLng() { + return endLng; + } + + public void setEndLng(String endLng) { + this.endLng = endLng; + } + + public String getEndLat() { + return endLat; + } + + public void setEndLat(String endLat) { + this.endLat = endLat; + } + + public String getEndAddress() { + return endAddress; + } + + public void setEndAddress(String endAddress) { + this.endAddress = endAddress; + } + + public LinkedList getRoutes() { + return routes; + } + + public void setRoutes(LinkedList routes) { + this.routes = routes; + } + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public void clearCache() { + this.id = ""; + this.name = ""; + this.startTime = ""; + this.endTime = ""; + this.date = ""; + this.startLng = ""; + this.startLat = ""; + this.startAddress = ""; + this.endLng = ""; + this.endLat = ""; + this.endAddress = ""; + this.routes.clear(); + this.user = ""; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.kt b/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.kt deleted file mode 100644 index f08334a..0000000 --- a/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.birmm.inspect.model - -import com.amap.api.maps.model.LatLng - -data class NewInspectionModel( - var id: String, - var name: String, - var startTime: String, - var endTime: String, - var date: String, - var startLng: Double, - var startLat: Double, - var startAddress: String, - var endLng: Double, - var endLat: Double, - var endAddress: String, - var routes: ArrayList, - var user: String -) \ No newline at end of file diff --git a/app/src/main/java/com/casic/birmm/inspect/single/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/birmm/inspect/single/fragment/HomePageFragment.kt index 031525e..76c7846 100644 --- a/app/src/main/java/com/casic/birmm/inspect/single/fragment/HomePageFragment.kt +++ b/app/src/main/java/com/casic/birmm/inspect/single/fragment/HomePageFragment.kt @@ -2,9 +2,14 @@ import android.bluetooth.BluetoothGatt import android.bluetooth.BluetoothGattCharacteristic +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.ServiceConnection import android.graphics.Color import android.os.Bundle import android.os.Handler +import android.os.IBinder import android.os.Message import android.os.Vibrator import android.util.Log @@ -30,6 +35,7 @@ import com.casic.birmm.inspect.extensions.toDeviceCode import com.casic.birmm.inspect.extensions.toDeviceModel import com.casic.birmm.inspect.model.NewInspectionModel +import com.casic.birmm.inspect.service.LocationService import com.casic.birmm.inspect.single.view.NewEventActivity import com.casic.birmm.inspect.utils.DataBaseManager import com.casic.birmm.inspect.utils.LocaleConstant @@ -93,12 +99,12 @@ private val kTag = "HomePageFragment" private val bleManager by lazy { BleManager.getInstance() } - private val latLngs = LinkedList() + private val newModel by lazy { NewInspectionModel() }//新建巡检数据结构模型 + private val latLngList by lazy { LinkedList() } private lateinit var aMap: AMap private lateinit var writeUuid: String private lateinit var notifyUuid: String private var vibrator: Vibrator? = null - private var newModel: NewInspectionModel? = null//新建巡检数据结构模型 private var connectedDevice: BleDevice? = null private var isGeneratingTask = false private var alarmCount = 0 @@ -136,48 +142,17 @@ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isCompassEnabled = true uiSettings.isZoomControlsEnabled = true + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 //显示定位小蓝点 val locationStyle = MyLocationStyle() - locationStyle.showMyLocation(true)//设置是否显示定位小蓝点 + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + //定位、移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE) aMap.myLocationStyle = locationStyle aMap.isMyLocationEnabled = true - aMap.mapType = AMap.MAP_TYPE_NORMAL - - LocationHub.get.getLocationByAMap(requireContext(), object : LocationHub.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - "当前信号弱,无法定位".show(requireContext()) - return - } - - val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) - - //移动到指定经纬度 - val cameraPosition = CameraPosition(latLng, 16f, 0f, 0f) - val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) - aMap.animateCamera(cameraUpdate, 1500, null) - - //newInspectionModel已完成初始化,说明已经新建巡检任务,数据可以开始保存了 - if (newModel != null) { - //设置巡检起点 - if (newModel!!.startAddress.isEmpty()) { - newModel!!.startAddress = aMapLocation.address - } - - //巡检终点每次定位都覆盖,降低调用sdk频率 - newModel!!.endAddress = aMapLocation.address - - latLngs.add(latLng) - - //绘制线 - aMap.addPolyline( - PolylineOptions().addAll(latLngs).width(10f).color(Color.RED) - ) - } - } - }) } override fun observeRequestState() { @@ -199,16 +174,25 @@ binding.inspectNameView.text = value binding.inspectTimeView.text = startTime - newModel = NewInspectionModel( - currentTimeMillis.id(), value, - startTime, "", currentTimeMillis.timestampToDate(), - 0.0, 0.0, "", 0.0, 0.0, "", - ArrayList(), "智巡宝" - ) + newModel.id = currentTimeMillis.id() + newModel.name = value + newModel.startTime = startTime + newModel.date = currentTimeMillis.timestampToDate() + newModel.user = "智巡宝" //按钮状态 binding.stopInspectButton.isEnabled = true binding.addInspectionButton.isEnabled = false + + locationService?.startLocation(object : LocationHub.ILocationListener { + override fun onAMapLocationGet(aMapLocation: AMapLocation) { + drawTaskRoute(aMapLocation) + } + + override fun onAMapLocationError() { + "当前信号弱,无法定位".show(requireContext()) + } + }) } override fun onCancelClick() { @@ -235,11 +219,11 @@ requireContext().navigatePageTo( addAll( position.toString(), - newModel!!.id, - newModel!!.name, + newModel.id, + newModel.name, connectedDeviceCode, - latLngs.last.longitude.toString(), - latLngs.last.latitude.toString() + newModel.routes.last.longitude.toString(), + newModel.routes.last.latitude.toString() ) ) } @@ -247,6 +231,33 @@ } } + private fun drawTaskRoute(aMapLocation: AMapLocation) { + Log.d(kTag, "${aMapLocation.latitude}, ${aMapLocation.longitude}") + val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) + + //移动到指定经纬度 + val cameraPosition = CameraPosition(latLng, 15f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + + //stopInspectButton isEnabled,说明已经新建巡检任务,数据可以开始保存了 + if (binding.stopInspectButton.isEnabled) { + latLngList.add(latLng) + newModel.routes = latLngList + + //设置巡检起点 + if (newModel.startAddress.isNullOrEmpty()) { + newModel.startAddress = aMapLocation.address + } + + //巡检终点每次定位都覆盖,降低调用sdk频率 + newModel.endAddress = aMapLocation.address + + //绘制线 + aMap.addPolyline(PolylineOptions().addAll(newModel.routes).width(10f).color(Color.RED)) + } + } + private fun menuButtonEvent() { //结束巡检 binding.stopInspectButton.setOnClickListener { @@ -296,8 +307,6 @@ //关闭数据传送指令 bleManager.disconnectAllDevice() - latLngs.clear() - aMap.clear()//清除原来的路线 SaveKeyValues.removeKey(LocaleConstant.DEVICE_CODE) withContext(Dispatchers.Main) { binding.currentValueView.text = "--" @@ -539,42 +548,51 @@ * * 如果保存到本地,则需要设置标识位,然后finish当前页面并提示 * */ - if (newModel == null) { - "保存失败".show(requireContext()) - return - } - LoadingDialogHub.show(requireActivity(), "数据保存中,请稍后...") + val routes = newModel.routes // 保存巡检位置点 lifecycleScope.launch(Dispatchers.Main) { withContext(Dispatchers.IO) { - for (i in 0 until latLngs.size) { - newModel!!.routes.add(latLngs[i]) - - DataBaseManager.get.addInspectionRoute(newModel!!.id, latLngs[i]) + for (i in 0 until routes.size) { + DataBaseManager.get.addInspectionRoute(newModel.id, routes[i]) } - DataBaseManager.get.addInspection( - inspectionId = newModel!!.id, - deviceCode = connectedDeviceCode, - inspectionName = newModel!!.name, - startTime = newModel!!.startTime, - endTime = System.currentTimeMillis().timestampToCompleteDate(), - date = newModel!!.date, - startLng = latLngs.first.longitude, - startLat = latLngs.first.latitude, - newModel!!.startAddress, - endLng = latLngs.last.longitude, - endLat = latLngs.last.latitude, - newModel!!.endAddress, - routes = newModel!!.routes - ) + try { + val first = routes.first + val last = routes.last + DataBaseManager.get.addInspection( + inspectionId = newModel.id, + deviceCode = connectedDeviceCode, + inspectionName = newModel.name, + startTime = newModel.startTime, + endTime = System.currentTimeMillis().timestampToCompleteDate(), + date = newModel.date, + startLng = first.longitude, + startLat = first.latitude, + startAddress = newModel.startAddress, + endLng = last.longitude, + endLat = last.latitude, + endAddress = newModel.endAddress, + routes = newModel.routes + ) + } catch (e: NoSuchElementException) { + e.printStackTrace() + withContext(Dispatchers.Main) { + "无定位数据,保存任务失败".show(requireContext()) + } + } } LoadingDialogHub.dismiss() + //清空newModel + newModel.clearCache() + + //停止定位 + locationService?.stopLocation() + //结束任务就清空轨迹 - latLngs.clear() + latLngList.clear() aMap.clear() //按钮状态 @@ -611,10 +629,6 @@ //如果连续超过10个报警,自动生成报警事件 alarmCount++ if (alarmCount >= 10) { - if (newModel == null) { - "没有巡检任务,无法自动记录报警".show(requireContext()) - return - } generateAlarmTask(dataModel.maxPotency) } } @@ -635,13 +649,13 @@ DataBaseManager.get.addEvent( taskId = UUID.randomUUID().toString(), - inspectionId = newModel!!.id, + inspectionId = newModel.id, deviceCode = connectedDeviceCode, - eventTitle = newModel!!.name, + eventTitle = newModel.name, createTime = System.currentTimeMillis().timestampToCompleteDate(), type = "报警事件", - lng = latLngs.last.longitude, - lat = latLngs.last.latitude, + lng = newModel.routes.last.longitude, + lat = newModel.routes.last.latitude, data = maxValue, images = "", description = "自动报警记录" @@ -671,11 +685,28 @@ } //设置标题和时间 - if (newModel == null) { - return + binding.inspectNameView.text = newModel.name + binding.inspectTimeView.text = newModel.startTime + + //绑定定位服务 + Intent(requireContext(), LocationService::class.java).also { + requireContext().bindService(it, serviceConnection, Context.BIND_AUTO_CREATE) } - binding.inspectNameView.text = newModel!!.name - binding.inspectTimeView.text = newModel!!.startTime + } + + private var locationService: LocationService? = null + + private val serviceConnection = object : ServiceConnection { + override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) { + if (iBinder is LocationService.ServiceBinder) { + locationService = iBinder.getLocationService() + Log.d(kTag, "onServiceConnected: ") + } + } + + override fun onServiceDisconnected(name: ComponentName?) { + "定位服务已断开".show(requireContext()) + } } override fun onPause() { diff --git a/app/src/main/java/com/casic/birmm/inspect/utils/DataBaseManager.kt b/app/src/main/java/com/casic/birmm/inspect/utils/DataBaseManager.kt index 3a2cac1..268f37b 100644 --- a/app/src/main/java/com/casic/birmm/inspect/utils/DataBaseManager.kt +++ b/app/src/main/java/com/casic/birmm/inspect/utils/DataBaseManager.kt @@ -12,6 +12,7 @@ import com.casic.birmm.inspect.greendao.TaskEventLocalBeanDao import com.casic.birmm.inspect.single.fragment.QueryEventFragment import com.casic.birmm.inspect.single.fragment.QueryInspectionFragment +import java.util.LinkedList class DataBaseManager private constructor() { @@ -44,7 +45,7 @@ endLng: Double, endLat: Double, endAddress: String, - routes: ArrayList + routes: LinkedList ) { val bean = InspectionLocalBean() bean.inspectionId = inspectionId diff --git a/app/src/main/java/com/casic/birmm/inspect/utils/LocationHub.kt b/app/src/main/java/com/casic/birmm/inspect/utils/LocationHub.kt index 11be914..5e12297 100644 --- a/app/src/main/java/com/casic/birmm/inspect/utils/LocationHub.kt +++ b/app/src/main/java/com/casic/birmm/inspect/utils/LocationHub.kt @@ -5,57 +5,54 @@ import com.amap.api.location.AMapLocation import com.amap.api.location.AMapLocationClient import com.amap.api.location.AMapLocationClientOption +import com.amap.api.location.AMapLocationListener class LocationHub private constructor() { private val kTag = "LocationHub" companion object { - //Kotlin委托模式双重锁单例 - val get: LocationHub by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { + val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { LocationHub() } } private val locationOption = AMapLocationClientOption() - private lateinit var locationClient: AMapLocationClient + private var locationClient: AMapLocationClient? = null init { //设置定位模式为高精度模式,AMapLocationMode.Battery_Saving为低功耗模式,AMapLocationMode.Device_Sensors是仅设备模式 locationOption.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy - locationOption.interval = 10 * 1000 //10s定位一次 locationOption.isNeedAddress = true //设置是否返回地址信息(默认返回地址信息) - locationOption.isLocationCacheEnable = true //可选,设置是否使用缓存定位,默认为true } /** * 高德sdk定位 */ - fun getLocationByAMap(context: Context?, listener: ILocationListener) { + fun getLocationByAMap(context: Context, listener: AMapLocationListener) { locationClient = AMapLocationClient(context) //给定位客户端对象设置定位参数 - locationClient.setLocationOption(locationOption) + locationClient?.setLocationOption(locationOption) //设置定位回调监听 - locationClient.setLocationListener { aMapLocation -> - if (aMapLocation != null) { - if (aMapLocation.errorCode == 0) { - listener.onAMapLocationGet(aMapLocation) + locationClient?.setLocationListener { + if (it != null) { + if (it.errorCode == 0) { + listener.onLocationChanged(it) } else { - Log.e( - kTag, - "ErrCode: ${aMapLocation.errorCode}, errInfo: ${aMapLocation.errorInfo}" - ) + Log.e(kTag, "errCode: ${it.errorCode}, errInfo: ${it.errorInfo}") } } } //启动定位 - locationClient.startLocation() + locationClient?.startLocation() } fun stopLocation() { - locationClient.stopLocation()//停止定位 + locationClient?.stopLocation()//停止定位 } interface ILocationListener { - fun onAMapLocationGet(aMapLocation: AMapLocation?) //高德定位数据 + fun onAMapLocationGet(aMapLocation: AMapLocation) //高德定位数据 + + fun onAMapLocationError() } } \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 9d0f82e..feb5ca9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -20,8 +20,8 @@ applicationId "com.casic.birmm.inspect" minSdkVersion 23 targetSdkVersion 33 - versionCode 1071 - versionName "1.0.7.1" + versionCode 1072 + versionName "1.0.7.2" } buildTypes { diff --git a/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt b/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt index 30b8f28..12c92e6 100644 --- a/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt @@ -1,12 +1,5 @@ package com.casic.birmm.inspect.extensions -import com.amap.api.maps.model.LatLng -import com.amap.api.services.core.LatLonPoint -import com.amap.api.services.route.DistanceSearch -import com.casic.birmm.inspect.base.BaseApplication -import com.casic.birmm.inspect.callback.OnDistanceSearchListener -import java.text.DecimalFormat - /** * ArrayList扩展方法 */ @@ -32,39 +25,4 @@ result.add(it) } return result -} - -private val distanceSearch by lazy { DistanceSearch(BaseApplication.get()) } -private val distanceQuery by lazy { DistanceSearch.DistanceQuery() } -private val decimalFormat by lazy { DecimalFormat("#.##") } - -fun ArrayList.calculateDistance(listener: OnDistanceSearchListener) { - if (this.isEmpty()) { - listener.onDistanceSearched("0.00") - } - - val last = this.last() - val dest = LatLonPoint(last.latitude, last.longitude) - - //去掉最后一个点 - this.removeLast() - val latLonPoints: ArrayList = ArrayList() - this.forEach { - latLonPoints.add(LatLonPoint(it.latitude, it.longitude)) - } - - distanceQuery.origins = latLonPoints - distanceQuery.destination = dest - distanceQuery.type = DistanceSearch.TYPE_WALK_DISTANCE - distanceSearch.calculateRouteDistanceAsyn(distanceQuery) - distanceSearch.setDistanceSearchListener { distanceResult, errorCode -> - if (errorCode == 1000) { - //DistanceResult返回的是单位是米 - val temp = distanceResult.distanceResults[0].distance - val distance = temp / 1000 - listener.onDistanceSearched(decimalFormat.format(distance)) - } else { - listener.onDistanceSearched("0.00") - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt index d5b1bc0..13b752f 100644 --- a/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt +++ b/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt @@ -2,9 +2,14 @@ import android.bluetooth.BluetoothGatt import android.bluetooth.BluetoothGattCharacteristic +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.ServiceConnection import android.graphics.Color import android.os.Bundle import android.os.Handler +import android.os.IBinder import android.os.Message import android.os.Vibrator import android.util.Log @@ -33,6 +38,7 @@ import com.casic.birmm.inspect.extensions.toDeviceCode import com.casic.birmm.inspect.extensions.toDeviceModel import com.casic.birmm.inspect.model.NewInspectionModel +import com.casic.birmm.inspect.service.LocationService import com.casic.birmm.inspect.utils.LocaleConstant import com.casic.birmm.inspect.utils.LocationHub import com.casic.birmm.inspect.utils.SoundPoolHelper @@ -99,7 +105,8 @@ private val kTag = "HomePageFragment" private val bleManager by lazy { BleManager.getInstance() } - private val latLngs = LinkedList() + private val newModel by lazy { NewInspectionModel() }//新建巡检数据结构模型 + private val latLngList by lazy { LinkedList() } private lateinit var userName: String private lateinit var eventViewModel: EventViewModel private lateinit var inspectionViewModel: InspectionViewModel @@ -108,7 +115,6 @@ private lateinit var writeUuid: String private lateinit var notifyUuid: String private var vibrator: Vibrator? = null - private var newModel: NewInspectionModel? = null//新建巡检数据结构模型 private var connectedDevice: BleDevice? = null private var isGeneratingTask = false private var alarmCount = 0 @@ -147,49 +153,19 @@ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isCompassEnabled = true uiSettings.isZoomControlsEnabled = true + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 //显示定位小蓝点 val locationStyle = MyLocationStyle() - locationStyle.showMyLocation(true)//设置是否显示定位小蓝点 + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + //定位、移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE) aMap.myLocationStyle = locationStyle aMap.isMyLocationEnabled = true aMap.mapType = AMap.MAP_TYPE_NORMAL - LocationHub.get.getLocationByAMap(requireContext(), object : LocationHub.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - "当前信号弱,无法定位".show(requireContext()) - return - } - - val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) - - //移动到指定经纬度 - val cameraPosition = CameraPosition(latLng, 16f, 0f, 0f) - val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) - aMap.animateCamera(cameraUpdate, 1500, null) - - //newInspectionModel已完成初始化,说明已经新建巡检任务,数据可以开始保存了 - if (newModel != null) { - //设置巡检起点 - if (newModel!!.startAddress.isEmpty()) { - newModel!!.startAddress = aMapLocation.address - } - - //巡检终点每次定位都覆盖,降低调用sdk频率 - newModel!!.endAddress = aMapLocation.address - - latLngs.add(latLng) - - //绘制线 - aMap.addPolyline( - PolylineOptions().addAll(latLngs).width(10f).color(Color.RED) - ) - } - } - }) - //UserName userName = SaveKeyValues.getValue(LocaleConstant.USER_NAME, "").toString() @@ -217,8 +193,11 @@ is LoadState.Success -> { LoadingDialogHub.dismiss() + //清空newModel + newModel.clearCache() + //结束任务就清空轨迹 - latLngs.clear() + latLngList.clear() aMap.clear() //按钮状态 @@ -248,16 +227,25 @@ binding.inspectNameView.text = value binding.inspectTimeView.text = startTime - newModel = NewInspectionModel( - currentTimeMillis.id(), value, - startTime, "", currentTimeMillis.timestampToDate(), - 0.0, 0.0, "", 0.0, 0.0, "", - ArrayList(), userName - ) + newModel.id = currentTimeMillis.id() + newModel.name = value + newModel.startTime = startTime + newModel.date = currentTimeMillis.timestampToDate() + newModel.user = userName //按钮状态 binding.stopInspectButton.isEnabled = true binding.addInspectionButton.isEnabled = false + + locationService?.startLocation(object : LocationHub.ILocationListener { + override fun onAMapLocationGet(aMapLocation: AMapLocation) { + drawTaskRoute(aMapLocation) + } + + override fun onAMapLocationError() { + "当前信号弱,无法定位".show(requireContext()) + } + }) } override fun onCancelClick() { @@ -284,11 +272,11 @@ requireContext().navigatePageTo( addAll( position.toString(), - newModel!!.id, - newModel!!.name, + newModel.id, + newModel.name, connectedDeviceCode, - latLngs.last.longitude.toString(), - latLngs.last.latitude.toString() + newModel.routes.last.longitude.toString(), + newModel.routes.last.latitude.toString() ) ) } @@ -296,6 +284,33 @@ } } + private fun drawTaskRoute(aMapLocation: AMapLocation) { + Log.d(kTag, "${aMapLocation.latitude}, ${aMapLocation.longitude}") + val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) + + //移动到指定经纬度 + val cameraPosition = CameraPosition(latLng, 15f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + + //stopInspectButton isEnabled,说明已经新建巡检任务,数据可以开始保存了 + if (binding.stopInspectButton.isEnabled) { + latLngList.add(latLng) + newModel.routes = latLngList + + //设置巡检起点 + if (newModel.startAddress.isNullOrEmpty()) { + newModel.startAddress = aMapLocation.address + } + + //巡检终点每次定位都覆盖,降低调用sdk频率 + newModel.endAddress = aMapLocation.address + + //绘制线 + aMap.addPolyline(PolylineOptions().addAll(newModel.routes).width(10f).color(Color.RED)) + } + } + private fun menuButtonEvent() { //结束巡检 binding.stopInspectButton.setOnClickListener { @@ -345,8 +360,6 @@ //关闭数据传送指令 bleManager.disconnectAllDevice() - latLngs.clear() - aMap.clear()//清除原来的路线 SaveKeyValues.removeKey(LocaleConstant.DEVICE_CODE) withContext(Dispatchers.Main) { binding.currentValueView.text = "--" @@ -588,44 +601,41 @@ * * 如果保存到本地,则需要设置标识位,然后finish当前页面并提示 * */ - if (newModel == null) { - "保存失败".show(requireContext()) - return - } - - // 上传巡检位置点 - for (i in 0 until latLngs.size) { - newModel!!.routes.add(latLngs[i]) + val routes = newModel.routes + for (i in 0 until routes.size) { //上传点位 routeViewModel.uploadRoutePoint( - newModel!!.id, - latLngs[i], - System.currentTimeMillis().timestampToCompleteDate() + newModel.id, routes[i], System.currentTimeMillis().timestampToCompleteDate() ) } - val first = latLngs.first - val last = latLngs.last - newModel!!.routes.calculateDistance(object : OnDistanceSearchListener { - override fun onDistanceSearched(distance: String) { - inspectionViewModel.addInspection( - id = newModel!!.id, - deviceCode = connectedDeviceCode, - name = newModel!!.name, - startTime = newModel!!.startTime, - endTime = System.currentTimeMillis().timestampToCompleteDate(), - date = newModel!!.date, - startLng = first.longitude, - startLat = first.latitude, - newModel!!.startAddress, - endLng = last.longitude, - endLat = last.latitude, - newModel!!.endAddress, - distance, - user = userName - ) - } - }) + try { + val first = routes.first + val last = routes.last + routes.calculateDistance(object : OnDistanceSearchListener { + override fun onDistanceSearched(distance: String) { + inspectionViewModel.addInspection( + id = newModel.id, + deviceCode = connectedDeviceCode, + name = newModel.name, + startTime = newModel.startTime, + endTime = System.currentTimeMillis().timestampToCompleteDate(), + date = newModel.date, + startLng = first.longitude, + startLat = first.latitude, + startAddress = newModel.startAddress, + endLng = last.longitude, + endLat = last.latitude, + endAddress = newModel.endAddress, + distance, + user = userName + ) + } + }) + } catch (e: NoSuchElementException) { + e.printStackTrace() + "无定位数据,保存任务失败".show(requireContext()) + } } /** @@ -657,10 +667,6 @@ //如果连续超过10个报警,自动生成报警事件 alarmCount++ if (alarmCount >= 10) { - if (newModel == null) { - "没有巡检任务,无法自动记录报警".show(requireContext()) - return - } generateAlarmTask(dataModel.maxPotency) } } @@ -680,12 +686,12 @@ eventViewModel.addEventTask( id = UUID.randomUUID().toString(), - inspectionId = newModel!!.id, - name = newModel!!.name, + inspectionId = newModel.id, + name = newModel.name, createTime = System.currentTimeMillis().timestampToCompleteDate(), type = "报警事件", - lng = latLngs.last.longitude, - lat = latLngs.last.latitude, + lng = newModel.routes.last.longitude, + lat = newModel.routes.last.latitude, data = maxValue, images = "", description = "自动报警记录", @@ -713,11 +719,28 @@ } //设置标题和时间 - if (newModel == null) { - return + binding.inspectNameView.text = newModel.name + binding.inspectTimeView.text = newModel.startTime + + //绑定定位服务 + Intent(requireContext(), LocationService::class.java).also { + requireContext().bindService(it, serviceConnection, Context.BIND_AUTO_CREATE) } - binding.inspectNameView.text = newModel!!.name - binding.inspectTimeView.text = newModel!!.startTime + } + + private var locationService: LocationService? = null + + private val serviceConnection = object : ServiceConnection { + override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) { + if (iBinder is LocationService.ServiceBinder) { + locationService = iBinder.getLocationService() + Log.d(kTag, "onServiceConnected: ") + } + } + + override fun onServiceDisconnected(name: ComponentName?) { + "定位服务已断开".show(requireContext()) + } } override fun onPause() { diff --git a/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.java b/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.java new file mode 100644 index 0000000..f09810f --- /dev/null +++ b/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.java @@ -0,0 +1,141 @@ +package com.casic.birmm.inspect.model; + +import com.amap.api.maps.model.LatLng; + +import java.util.LinkedList; + +public class NewInspectionModel { + private String id; + private String name; + private String startTime; + private String endTime; + private String date; + private String startLng; + private String startLat; + private String startAddress; + private String endLng; + private String endLat; + private String endAddress; + private LinkedList routes; + private String user; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + + public String getEndTime() { + return endTime; + } + + public void setEndTime(String endTime) { + this.endTime = endTime; + } + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } + + public String getStartLng() { + return startLng; + } + + public void setStartLng(String startLng) { + this.startLng = startLng; + } + + public String getStartLat() { + return startLat; + } + + public void setStartLat(String startLat) { + this.startLat = startLat; + } + + public String getStartAddress() { + return startAddress; + } + + public void setStartAddress(String startAddress) { + this.startAddress = startAddress; + } + + public String getEndLng() { + return endLng; + } + + public void setEndLng(String endLng) { + this.endLng = endLng; + } + + public String getEndLat() { + return endLat; + } + + public void setEndLat(String endLat) { + this.endLat = endLat; + } + + public String getEndAddress() { + return endAddress; + } + + public void setEndAddress(String endAddress) { + this.endAddress = endAddress; + } + + public LinkedList getRoutes() { + return routes; + } + + public void setRoutes(LinkedList routes) { + this.routes = routes; + } + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public void clearCache() { + this.id = ""; + this.name = ""; + this.startTime = ""; + this.endTime = ""; + this.date = ""; + this.startLng = ""; + this.startLat = ""; + this.startAddress = ""; + this.endLng = ""; + this.endLat = ""; + this.endAddress = ""; + this.routes.clear(); + this.user = ""; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.kt b/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.kt deleted file mode 100644 index f08334a..0000000 --- a/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.birmm.inspect.model - -import com.amap.api.maps.model.LatLng - -data class NewInspectionModel( - var id: String, - var name: String, - var startTime: String, - var endTime: String, - var date: String, - var startLng: Double, - var startLat: Double, - var startAddress: String, - var endLng: Double, - var endLat: Double, - var endAddress: String, - var routes: ArrayList, - var user: String -) \ No newline at end of file diff --git a/app/src/main/java/com/casic/birmm/inspect/single/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/birmm/inspect/single/fragment/HomePageFragment.kt index 031525e..76c7846 100644 --- a/app/src/main/java/com/casic/birmm/inspect/single/fragment/HomePageFragment.kt +++ b/app/src/main/java/com/casic/birmm/inspect/single/fragment/HomePageFragment.kt @@ -2,9 +2,14 @@ import android.bluetooth.BluetoothGatt import android.bluetooth.BluetoothGattCharacteristic +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.ServiceConnection import android.graphics.Color import android.os.Bundle import android.os.Handler +import android.os.IBinder import android.os.Message import android.os.Vibrator import android.util.Log @@ -30,6 +35,7 @@ import com.casic.birmm.inspect.extensions.toDeviceCode import com.casic.birmm.inspect.extensions.toDeviceModel import com.casic.birmm.inspect.model.NewInspectionModel +import com.casic.birmm.inspect.service.LocationService import com.casic.birmm.inspect.single.view.NewEventActivity import com.casic.birmm.inspect.utils.DataBaseManager import com.casic.birmm.inspect.utils.LocaleConstant @@ -93,12 +99,12 @@ private val kTag = "HomePageFragment" private val bleManager by lazy { BleManager.getInstance() } - private val latLngs = LinkedList() + private val newModel by lazy { NewInspectionModel() }//新建巡检数据结构模型 + private val latLngList by lazy { LinkedList() } private lateinit var aMap: AMap private lateinit var writeUuid: String private lateinit var notifyUuid: String private var vibrator: Vibrator? = null - private var newModel: NewInspectionModel? = null//新建巡检数据结构模型 private var connectedDevice: BleDevice? = null private var isGeneratingTask = false private var alarmCount = 0 @@ -136,48 +142,17 @@ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isCompassEnabled = true uiSettings.isZoomControlsEnabled = true + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 //显示定位小蓝点 val locationStyle = MyLocationStyle() - locationStyle.showMyLocation(true)//设置是否显示定位小蓝点 + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + //定位、移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE) aMap.myLocationStyle = locationStyle aMap.isMyLocationEnabled = true - aMap.mapType = AMap.MAP_TYPE_NORMAL - - LocationHub.get.getLocationByAMap(requireContext(), object : LocationHub.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - "当前信号弱,无法定位".show(requireContext()) - return - } - - val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) - - //移动到指定经纬度 - val cameraPosition = CameraPosition(latLng, 16f, 0f, 0f) - val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) - aMap.animateCamera(cameraUpdate, 1500, null) - - //newInspectionModel已完成初始化,说明已经新建巡检任务,数据可以开始保存了 - if (newModel != null) { - //设置巡检起点 - if (newModel!!.startAddress.isEmpty()) { - newModel!!.startAddress = aMapLocation.address - } - - //巡检终点每次定位都覆盖,降低调用sdk频率 - newModel!!.endAddress = aMapLocation.address - - latLngs.add(latLng) - - //绘制线 - aMap.addPolyline( - PolylineOptions().addAll(latLngs).width(10f).color(Color.RED) - ) - } - } - }) } override fun observeRequestState() { @@ -199,16 +174,25 @@ binding.inspectNameView.text = value binding.inspectTimeView.text = startTime - newModel = NewInspectionModel( - currentTimeMillis.id(), value, - startTime, "", currentTimeMillis.timestampToDate(), - 0.0, 0.0, "", 0.0, 0.0, "", - ArrayList(), "智巡宝" - ) + newModel.id = currentTimeMillis.id() + newModel.name = value + newModel.startTime = startTime + newModel.date = currentTimeMillis.timestampToDate() + newModel.user = "智巡宝" //按钮状态 binding.stopInspectButton.isEnabled = true binding.addInspectionButton.isEnabled = false + + locationService?.startLocation(object : LocationHub.ILocationListener { + override fun onAMapLocationGet(aMapLocation: AMapLocation) { + drawTaskRoute(aMapLocation) + } + + override fun onAMapLocationError() { + "当前信号弱,无法定位".show(requireContext()) + } + }) } override fun onCancelClick() { @@ -235,11 +219,11 @@ requireContext().navigatePageTo( addAll( position.toString(), - newModel!!.id, - newModel!!.name, + newModel.id, + newModel.name, connectedDeviceCode, - latLngs.last.longitude.toString(), - latLngs.last.latitude.toString() + newModel.routes.last.longitude.toString(), + newModel.routes.last.latitude.toString() ) ) } @@ -247,6 +231,33 @@ } } + private fun drawTaskRoute(aMapLocation: AMapLocation) { + Log.d(kTag, "${aMapLocation.latitude}, ${aMapLocation.longitude}") + val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) + + //移动到指定经纬度 + val cameraPosition = CameraPosition(latLng, 15f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + + //stopInspectButton isEnabled,说明已经新建巡检任务,数据可以开始保存了 + if (binding.stopInspectButton.isEnabled) { + latLngList.add(latLng) + newModel.routes = latLngList + + //设置巡检起点 + if (newModel.startAddress.isNullOrEmpty()) { + newModel.startAddress = aMapLocation.address + } + + //巡检终点每次定位都覆盖,降低调用sdk频率 + newModel.endAddress = aMapLocation.address + + //绘制线 + aMap.addPolyline(PolylineOptions().addAll(newModel.routes).width(10f).color(Color.RED)) + } + } + private fun menuButtonEvent() { //结束巡检 binding.stopInspectButton.setOnClickListener { @@ -296,8 +307,6 @@ //关闭数据传送指令 bleManager.disconnectAllDevice() - latLngs.clear() - aMap.clear()//清除原来的路线 SaveKeyValues.removeKey(LocaleConstant.DEVICE_CODE) withContext(Dispatchers.Main) { binding.currentValueView.text = "--" @@ -539,42 +548,51 @@ * * 如果保存到本地,则需要设置标识位,然后finish当前页面并提示 * */ - if (newModel == null) { - "保存失败".show(requireContext()) - return - } - LoadingDialogHub.show(requireActivity(), "数据保存中,请稍后...") + val routes = newModel.routes // 保存巡检位置点 lifecycleScope.launch(Dispatchers.Main) { withContext(Dispatchers.IO) { - for (i in 0 until latLngs.size) { - newModel!!.routes.add(latLngs[i]) - - DataBaseManager.get.addInspectionRoute(newModel!!.id, latLngs[i]) + for (i in 0 until routes.size) { + DataBaseManager.get.addInspectionRoute(newModel.id, routes[i]) } - DataBaseManager.get.addInspection( - inspectionId = newModel!!.id, - deviceCode = connectedDeviceCode, - inspectionName = newModel!!.name, - startTime = newModel!!.startTime, - endTime = System.currentTimeMillis().timestampToCompleteDate(), - date = newModel!!.date, - startLng = latLngs.first.longitude, - startLat = latLngs.first.latitude, - newModel!!.startAddress, - endLng = latLngs.last.longitude, - endLat = latLngs.last.latitude, - newModel!!.endAddress, - routes = newModel!!.routes - ) + try { + val first = routes.first + val last = routes.last + DataBaseManager.get.addInspection( + inspectionId = newModel.id, + deviceCode = connectedDeviceCode, + inspectionName = newModel.name, + startTime = newModel.startTime, + endTime = System.currentTimeMillis().timestampToCompleteDate(), + date = newModel.date, + startLng = first.longitude, + startLat = first.latitude, + startAddress = newModel.startAddress, + endLng = last.longitude, + endLat = last.latitude, + endAddress = newModel.endAddress, + routes = newModel.routes + ) + } catch (e: NoSuchElementException) { + e.printStackTrace() + withContext(Dispatchers.Main) { + "无定位数据,保存任务失败".show(requireContext()) + } + } } LoadingDialogHub.dismiss() + //清空newModel + newModel.clearCache() + + //停止定位 + locationService?.stopLocation() + //结束任务就清空轨迹 - latLngs.clear() + latLngList.clear() aMap.clear() //按钮状态 @@ -611,10 +629,6 @@ //如果连续超过10个报警,自动生成报警事件 alarmCount++ if (alarmCount >= 10) { - if (newModel == null) { - "没有巡检任务,无法自动记录报警".show(requireContext()) - return - } generateAlarmTask(dataModel.maxPotency) } } @@ -635,13 +649,13 @@ DataBaseManager.get.addEvent( taskId = UUID.randomUUID().toString(), - inspectionId = newModel!!.id, + inspectionId = newModel.id, deviceCode = connectedDeviceCode, - eventTitle = newModel!!.name, + eventTitle = newModel.name, createTime = System.currentTimeMillis().timestampToCompleteDate(), type = "报警事件", - lng = latLngs.last.longitude, - lat = latLngs.last.latitude, + lng = newModel.routes.last.longitude, + lat = newModel.routes.last.latitude, data = maxValue, images = "", description = "自动报警记录" @@ -671,11 +685,28 @@ } //设置标题和时间 - if (newModel == null) { - return + binding.inspectNameView.text = newModel.name + binding.inspectTimeView.text = newModel.startTime + + //绑定定位服务 + Intent(requireContext(), LocationService::class.java).also { + requireContext().bindService(it, serviceConnection, Context.BIND_AUTO_CREATE) } - binding.inspectNameView.text = newModel!!.name - binding.inspectTimeView.text = newModel!!.startTime + } + + private var locationService: LocationService? = null + + private val serviceConnection = object : ServiceConnection { + override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) { + if (iBinder is LocationService.ServiceBinder) { + locationService = iBinder.getLocationService() + Log.d(kTag, "onServiceConnected: ") + } + } + + override fun onServiceDisconnected(name: ComponentName?) { + "定位服务已断开".show(requireContext()) + } } override fun onPause() { diff --git a/app/src/main/java/com/casic/birmm/inspect/utils/DataBaseManager.kt b/app/src/main/java/com/casic/birmm/inspect/utils/DataBaseManager.kt index 3a2cac1..268f37b 100644 --- a/app/src/main/java/com/casic/birmm/inspect/utils/DataBaseManager.kt +++ b/app/src/main/java/com/casic/birmm/inspect/utils/DataBaseManager.kt @@ -12,6 +12,7 @@ import com.casic.birmm.inspect.greendao.TaskEventLocalBeanDao import com.casic.birmm.inspect.single.fragment.QueryEventFragment import com.casic.birmm.inspect.single.fragment.QueryInspectionFragment +import java.util.LinkedList class DataBaseManager private constructor() { @@ -44,7 +45,7 @@ endLng: Double, endLat: Double, endAddress: String, - routes: ArrayList + routes: LinkedList ) { val bean = InspectionLocalBean() bean.inspectionId = inspectionId diff --git a/app/src/main/java/com/casic/birmm/inspect/utils/LocationHub.kt b/app/src/main/java/com/casic/birmm/inspect/utils/LocationHub.kt index 11be914..5e12297 100644 --- a/app/src/main/java/com/casic/birmm/inspect/utils/LocationHub.kt +++ b/app/src/main/java/com/casic/birmm/inspect/utils/LocationHub.kt @@ -5,57 +5,54 @@ import com.amap.api.location.AMapLocation import com.amap.api.location.AMapLocationClient import com.amap.api.location.AMapLocationClientOption +import com.amap.api.location.AMapLocationListener class LocationHub private constructor() { private val kTag = "LocationHub" companion object { - //Kotlin委托模式双重锁单例 - val get: LocationHub by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { + val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { LocationHub() } } private val locationOption = AMapLocationClientOption() - private lateinit var locationClient: AMapLocationClient + private var locationClient: AMapLocationClient? = null init { //设置定位模式为高精度模式,AMapLocationMode.Battery_Saving为低功耗模式,AMapLocationMode.Device_Sensors是仅设备模式 locationOption.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy - locationOption.interval = 10 * 1000 //10s定位一次 locationOption.isNeedAddress = true //设置是否返回地址信息(默认返回地址信息) - locationOption.isLocationCacheEnable = true //可选,设置是否使用缓存定位,默认为true } /** * 高德sdk定位 */ - fun getLocationByAMap(context: Context?, listener: ILocationListener) { + fun getLocationByAMap(context: Context, listener: AMapLocationListener) { locationClient = AMapLocationClient(context) //给定位客户端对象设置定位参数 - locationClient.setLocationOption(locationOption) + locationClient?.setLocationOption(locationOption) //设置定位回调监听 - locationClient.setLocationListener { aMapLocation -> - if (aMapLocation != null) { - if (aMapLocation.errorCode == 0) { - listener.onAMapLocationGet(aMapLocation) + locationClient?.setLocationListener { + if (it != null) { + if (it.errorCode == 0) { + listener.onLocationChanged(it) } else { - Log.e( - kTag, - "ErrCode: ${aMapLocation.errorCode}, errInfo: ${aMapLocation.errorInfo}" - ) + Log.e(kTag, "errCode: ${it.errorCode}, errInfo: ${it.errorInfo}") } } } //启动定位 - locationClient.startLocation() + locationClient?.startLocation() } fun stopLocation() { - locationClient.stopLocation()//停止定位 + locationClient?.stopLocation()//停止定位 } interface ILocationListener { - fun onAMapLocationGet(aMapLocation: AMapLocation?) //高德定位数据 + fun onAMapLocationGet(aMapLocation: AMapLocation) //高德定位数据 + + fun onAMapLocationError() } } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_event_detail.xml b/app/src/main/res/layout/activity_event_detail.xml index d8dc39e..aa8cdf3 100644 --- a/app/src/main/res/layout/activity_event_detail.xml +++ b/app/src/main/res/layout/activity_event_detail.xml @@ -97,7 +97,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" - android:text="最大泄露数值" + android:text="最大泄露数值(ppm · m)" android:textColor="@color/black" android:textSize="@dimen/sp_16" /> diff --git a/app/build.gradle b/app/build.gradle index 9d0f82e..feb5ca9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -20,8 +20,8 @@ applicationId "com.casic.birmm.inspect" minSdkVersion 23 targetSdkVersion 33 - versionCode 1071 - versionName "1.0.7.1" + versionCode 1072 + versionName "1.0.7.2" } buildTypes { diff --git a/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt b/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt index 30b8f28..12c92e6 100644 --- a/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt @@ -1,12 +1,5 @@ package com.casic.birmm.inspect.extensions -import com.amap.api.maps.model.LatLng -import com.amap.api.services.core.LatLonPoint -import com.amap.api.services.route.DistanceSearch -import com.casic.birmm.inspect.base.BaseApplication -import com.casic.birmm.inspect.callback.OnDistanceSearchListener -import java.text.DecimalFormat - /** * ArrayList扩展方法 */ @@ -32,39 +25,4 @@ result.add(it) } return result -} - -private val distanceSearch by lazy { DistanceSearch(BaseApplication.get()) } -private val distanceQuery by lazy { DistanceSearch.DistanceQuery() } -private val decimalFormat by lazy { DecimalFormat("#.##") } - -fun ArrayList.calculateDistance(listener: OnDistanceSearchListener) { - if (this.isEmpty()) { - listener.onDistanceSearched("0.00") - } - - val last = this.last() - val dest = LatLonPoint(last.latitude, last.longitude) - - //去掉最后一个点 - this.removeLast() - val latLonPoints: ArrayList = ArrayList() - this.forEach { - latLonPoints.add(LatLonPoint(it.latitude, it.longitude)) - } - - distanceQuery.origins = latLonPoints - distanceQuery.destination = dest - distanceQuery.type = DistanceSearch.TYPE_WALK_DISTANCE - distanceSearch.calculateRouteDistanceAsyn(distanceQuery) - distanceSearch.setDistanceSearchListener { distanceResult, errorCode -> - if (errorCode == 1000) { - //DistanceResult返回的是单位是米 - val temp = distanceResult.distanceResults[0].distance - val distance = temp / 1000 - listener.onDistanceSearched(decimalFormat.format(distance)) - } else { - listener.onDistanceSearched("0.00") - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt index d5b1bc0..13b752f 100644 --- a/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt +++ b/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt @@ -2,9 +2,14 @@ import android.bluetooth.BluetoothGatt import android.bluetooth.BluetoothGattCharacteristic +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.ServiceConnection import android.graphics.Color import android.os.Bundle import android.os.Handler +import android.os.IBinder import android.os.Message import android.os.Vibrator import android.util.Log @@ -33,6 +38,7 @@ import com.casic.birmm.inspect.extensions.toDeviceCode import com.casic.birmm.inspect.extensions.toDeviceModel import com.casic.birmm.inspect.model.NewInspectionModel +import com.casic.birmm.inspect.service.LocationService import com.casic.birmm.inspect.utils.LocaleConstant import com.casic.birmm.inspect.utils.LocationHub import com.casic.birmm.inspect.utils.SoundPoolHelper @@ -99,7 +105,8 @@ private val kTag = "HomePageFragment" private val bleManager by lazy { BleManager.getInstance() } - private val latLngs = LinkedList() + private val newModel by lazy { NewInspectionModel() }//新建巡检数据结构模型 + private val latLngList by lazy { LinkedList() } private lateinit var userName: String private lateinit var eventViewModel: EventViewModel private lateinit var inspectionViewModel: InspectionViewModel @@ -108,7 +115,6 @@ private lateinit var writeUuid: String private lateinit var notifyUuid: String private var vibrator: Vibrator? = null - private var newModel: NewInspectionModel? = null//新建巡检数据结构模型 private var connectedDevice: BleDevice? = null private var isGeneratingTask = false private var alarmCount = 0 @@ -147,49 +153,19 @@ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isCompassEnabled = true uiSettings.isZoomControlsEnabled = true + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 //显示定位小蓝点 val locationStyle = MyLocationStyle() - locationStyle.showMyLocation(true)//设置是否显示定位小蓝点 + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + //定位、移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE) aMap.myLocationStyle = locationStyle aMap.isMyLocationEnabled = true aMap.mapType = AMap.MAP_TYPE_NORMAL - LocationHub.get.getLocationByAMap(requireContext(), object : LocationHub.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - "当前信号弱,无法定位".show(requireContext()) - return - } - - val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) - - //移动到指定经纬度 - val cameraPosition = CameraPosition(latLng, 16f, 0f, 0f) - val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) - aMap.animateCamera(cameraUpdate, 1500, null) - - //newInspectionModel已完成初始化,说明已经新建巡检任务,数据可以开始保存了 - if (newModel != null) { - //设置巡检起点 - if (newModel!!.startAddress.isEmpty()) { - newModel!!.startAddress = aMapLocation.address - } - - //巡检终点每次定位都覆盖,降低调用sdk频率 - newModel!!.endAddress = aMapLocation.address - - latLngs.add(latLng) - - //绘制线 - aMap.addPolyline( - PolylineOptions().addAll(latLngs).width(10f).color(Color.RED) - ) - } - } - }) - //UserName userName = SaveKeyValues.getValue(LocaleConstant.USER_NAME, "").toString() @@ -217,8 +193,11 @@ is LoadState.Success -> { LoadingDialogHub.dismiss() + //清空newModel + newModel.clearCache() + //结束任务就清空轨迹 - latLngs.clear() + latLngList.clear() aMap.clear() //按钮状态 @@ -248,16 +227,25 @@ binding.inspectNameView.text = value binding.inspectTimeView.text = startTime - newModel = NewInspectionModel( - currentTimeMillis.id(), value, - startTime, "", currentTimeMillis.timestampToDate(), - 0.0, 0.0, "", 0.0, 0.0, "", - ArrayList(), userName - ) + newModel.id = currentTimeMillis.id() + newModel.name = value + newModel.startTime = startTime + newModel.date = currentTimeMillis.timestampToDate() + newModel.user = userName //按钮状态 binding.stopInspectButton.isEnabled = true binding.addInspectionButton.isEnabled = false + + locationService?.startLocation(object : LocationHub.ILocationListener { + override fun onAMapLocationGet(aMapLocation: AMapLocation) { + drawTaskRoute(aMapLocation) + } + + override fun onAMapLocationError() { + "当前信号弱,无法定位".show(requireContext()) + } + }) } override fun onCancelClick() { @@ -284,11 +272,11 @@ requireContext().navigatePageTo( addAll( position.toString(), - newModel!!.id, - newModel!!.name, + newModel.id, + newModel.name, connectedDeviceCode, - latLngs.last.longitude.toString(), - latLngs.last.latitude.toString() + newModel.routes.last.longitude.toString(), + newModel.routes.last.latitude.toString() ) ) } @@ -296,6 +284,33 @@ } } + private fun drawTaskRoute(aMapLocation: AMapLocation) { + Log.d(kTag, "${aMapLocation.latitude}, ${aMapLocation.longitude}") + val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) + + //移动到指定经纬度 + val cameraPosition = CameraPosition(latLng, 15f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + + //stopInspectButton isEnabled,说明已经新建巡检任务,数据可以开始保存了 + if (binding.stopInspectButton.isEnabled) { + latLngList.add(latLng) + newModel.routes = latLngList + + //设置巡检起点 + if (newModel.startAddress.isNullOrEmpty()) { + newModel.startAddress = aMapLocation.address + } + + //巡检终点每次定位都覆盖,降低调用sdk频率 + newModel.endAddress = aMapLocation.address + + //绘制线 + aMap.addPolyline(PolylineOptions().addAll(newModel.routes).width(10f).color(Color.RED)) + } + } + private fun menuButtonEvent() { //结束巡检 binding.stopInspectButton.setOnClickListener { @@ -345,8 +360,6 @@ //关闭数据传送指令 bleManager.disconnectAllDevice() - latLngs.clear() - aMap.clear()//清除原来的路线 SaveKeyValues.removeKey(LocaleConstant.DEVICE_CODE) withContext(Dispatchers.Main) { binding.currentValueView.text = "--" @@ -588,44 +601,41 @@ * * 如果保存到本地,则需要设置标识位,然后finish当前页面并提示 * */ - if (newModel == null) { - "保存失败".show(requireContext()) - return - } - - // 上传巡检位置点 - for (i in 0 until latLngs.size) { - newModel!!.routes.add(latLngs[i]) + val routes = newModel.routes + for (i in 0 until routes.size) { //上传点位 routeViewModel.uploadRoutePoint( - newModel!!.id, - latLngs[i], - System.currentTimeMillis().timestampToCompleteDate() + newModel.id, routes[i], System.currentTimeMillis().timestampToCompleteDate() ) } - val first = latLngs.first - val last = latLngs.last - newModel!!.routes.calculateDistance(object : OnDistanceSearchListener { - override fun onDistanceSearched(distance: String) { - inspectionViewModel.addInspection( - id = newModel!!.id, - deviceCode = connectedDeviceCode, - name = newModel!!.name, - startTime = newModel!!.startTime, - endTime = System.currentTimeMillis().timestampToCompleteDate(), - date = newModel!!.date, - startLng = first.longitude, - startLat = first.latitude, - newModel!!.startAddress, - endLng = last.longitude, - endLat = last.latitude, - newModel!!.endAddress, - distance, - user = userName - ) - } - }) + try { + val first = routes.first + val last = routes.last + routes.calculateDistance(object : OnDistanceSearchListener { + override fun onDistanceSearched(distance: String) { + inspectionViewModel.addInspection( + id = newModel.id, + deviceCode = connectedDeviceCode, + name = newModel.name, + startTime = newModel.startTime, + endTime = System.currentTimeMillis().timestampToCompleteDate(), + date = newModel.date, + startLng = first.longitude, + startLat = first.latitude, + startAddress = newModel.startAddress, + endLng = last.longitude, + endLat = last.latitude, + endAddress = newModel.endAddress, + distance, + user = userName + ) + } + }) + } catch (e: NoSuchElementException) { + e.printStackTrace() + "无定位数据,保存任务失败".show(requireContext()) + } } /** @@ -657,10 +667,6 @@ //如果连续超过10个报警,自动生成报警事件 alarmCount++ if (alarmCount >= 10) { - if (newModel == null) { - "没有巡检任务,无法自动记录报警".show(requireContext()) - return - } generateAlarmTask(dataModel.maxPotency) } } @@ -680,12 +686,12 @@ eventViewModel.addEventTask( id = UUID.randomUUID().toString(), - inspectionId = newModel!!.id, - name = newModel!!.name, + inspectionId = newModel.id, + name = newModel.name, createTime = System.currentTimeMillis().timestampToCompleteDate(), type = "报警事件", - lng = latLngs.last.longitude, - lat = latLngs.last.latitude, + lng = newModel.routes.last.longitude, + lat = newModel.routes.last.latitude, data = maxValue, images = "", description = "自动报警记录", @@ -713,11 +719,28 @@ } //设置标题和时间 - if (newModel == null) { - return + binding.inspectNameView.text = newModel.name + binding.inspectTimeView.text = newModel.startTime + + //绑定定位服务 + Intent(requireContext(), LocationService::class.java).also { + requireContext().bindService(it, serviceConnection, Context.BIND_AUTO_CREATE) } - binding.inspectNameView.text = newModel!!.name - binding.inspectTimeView.text = newModel!!.startTime + } + + private var locationService: LocationService? = null + + private val serviceConnection = object : ServiceConnection { + override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) { + if (iBinder is LocationService.ServiceBinder) { + locationService = iBinder.getLocationService() + Log.d(kTag, "onServiceConnected: ") + } + } + + override fun onServiceDisconnected(name: ComponentName?) { + "定位服务已断开".show(requireContext()) + } } override fun onPause() { diff --git a/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.java b/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.java new file mode 100644 index 0000000..f09810f --- /dev/null +++ b/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.java @@ -0,0 +1,141 @@ +package com.casic.birmm.inspect.model; + +import com.amap.api.maps.model.LatLng; + +import java.util.LinkedList; + +public class NewInspectionModel { + private String id; + private String name; + private String startTime; + private String endTime; + private String date; + private String startLng; + private String startLat; + private String startAddress; + private String endLng; + private String endLat; + private String endAddress; + private LinkedList routes; + private String user; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + + public String getEndTime() { + return endTime; + } + + public void setEndTime(String endTime) { + this.endTime = endTime; + } + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } + + public String getStartLng() { + return startLng; + } + + public void setStartLng(String startLng) { + this.startLng = startLng; + } + + public String getStartLat() { + return startLat; + } + + public void setStartLat(String startLat) { + this.startLat = startLat; + } + + public String getStartAddress() { + return startAddress; + } + + public void setStartAddress(String startAddress) { + this.startAddress = startAddress; + } + + public String getEndLng() { + return endLng; + } + + public void setEndLng(String endLng) { + this.endLng = endLng; + } + + public String getEndLat() { + return endLat; + } + + public void setEndLat(String endLat) { + this.endLat = endLat; + } + + public String getEndAddress() { + return endAddress; + } + + public void setEndAddress(String endAddress) { + this.endAddress = endAddress; + } + + public LinkedList getRoutes() { + return routes; + } + + public void setRoutes(LinkedList routes) { + this.routes = routes; + } + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public void clearCache() { + this.id = ""; + this.name = ""; + this.startTime = ""; + this.endTime = ""; + this.date = ""; + this.startLng = ""; + this.startLat = ""; + this.startAddress = ""; + this.endLng = ""; + this.endLat = ""; + this.endAddress = ""; + this.routes.clear(); + this.user = ""; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.kt b/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.kt deleted file mode 100644 index f08334a..0000000 --- a/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.birmm.inspect.model - -import com.amap.api.maps.model.LatLng - -data class NewInspectionModel( - var id: String, - var name: String, - var startTime: String, - var endTime: String, - var date: String, - var startLng: Double, - var startLat: Double, - var startAddress: String, - var endLng: Double, - var endLat: Double, - var endAddress: String, - var routes: ArrayList, - var user: String -) \ No newline at end of file diff --git a/app/src/main/java/com/casic/birmm/inspect/single/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/birmm/inspect/single/fragment/HomePageFragment.kt index 031525e..76c7846 100644 --- a/app/src/main/java/com/casic/birmm/inspect/single/fragment/HomePageFragment.kt +++ b/app/src/main/java/com/casic/birmm/inspect/single/fragment/HomePageFragment.kt @@ -2,9 +2,14 @@ import android.bluetooth.BluetoothGatt import android.bluetooth.BluetoothGattCharacteristic +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.ServiceConnection import android.graphics.Color import android.os.Bundle import android.os.Handler +import android.os.IBinder import android.os.Message import android.os.Vibrator import android.util.Log @@ -30,6 +35,7 @@ import com.casic.birmm.inspect.extensions.toDeviceCode import com.casic.birmm.inspect.extensions.toDeviceModel import com.casic.birmm.inspect.model.NewInspectionModel +import com.casic.birmm.inspect.service.LocationService import com.casic.birmm.inspect.single.view.NewEventActivity import com.casic.birmm.inspect.utils.DataBaseManager import com.casic.birmm.inspect.utils.LocaleConstant @@ -93,12 +99,12 @@ private val kTag = "HomePageFragment" private val bleManager by lazy { BleManager.getInstance() } - private val latLngs = LinkedList() + private val newModel by lazy { NewInspectionModel() }//新建巡检数据结构模型 + private val latLngList by lazy { LinkedList() } private lateinit var aMap: AMap private lateinit var writeUuid: String private lateinit var notifyUuid: String private var vibrator: Vibrator? = null - private var newModel: NewInspectionModel? = null//新建巡检数据结构模型 private var connectedDevice: BleDevice? = null private var isGeneratingTask = false private var alarmCount = 0 @@ -136,48 +142,17 @@ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isCompassEnabled = true uiSettings.isZoomControlsEnabled = true + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 //显示定位小蓝点 val locationStyle = MyLocationStyle() - locationStyle.showMyLocation(true)//设置是否显示定位小蓝点 + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + //定位、移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE) aMap.myLocationStyle = locationStyle aMap.isMyLocationEnabled = true - aMap.mapType = AMap.MAP_TYPE_NORMAL - - LocationHub.get.getLocationByAMap(requireContext(), object : LocationHub.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - "当前信号弱,无法定位".show(requireContext()) - return - } - - val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) - - //移动到指定经纬度 - val cameraPosition = CameraPosition(latLng, 16f, 0f, 0f) - val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) - aMap.animateCamera(cameraUpdate, 1500, null) - - //newInspectionModel已完成初始化,说明已经新建巡检任务,数据可以开始保存了 - if (newModel != null) { - //设置巡检起点 - if (newModel!!.startAddress.isEmpty()) { - newModel!!.startAddress = aMapLocation.address - } - - //巡检终点每次定位都覆盖,降低调用sdk频率 - newModel!!.endAddress = aMapLocation.address - - latLngs.add(latLng) - - //绘制线 - aMap.addPolyline( - PolylineOptions().addAll(latLngs).width(10f).color(Color.RED) - ) - } - } - }) } override fun observeRequestState() { @@ -199,16 +174,25 @@ binding.inspectNameView.text = value binding.inspectTimeView.text = startTime - newModel = NewInspectionModel( - currentTimeMillis.id(), value, - startTime, "", currentTimeMillis.timestampToDate(), - 0.0, 0.0, "", 0.0, 0.0, "", - ArrayList(), "智巡宝" - ) + newModel.id = currentTimeMillis.id() + newModel.name = value + newModel.startTime = startTime + newModel.date = currentTimeMillis.timestampToDate() + newModel.user = "智巡宝" //按钮状态 binding.stopInspectButton.isEnabled = true binding.addInspectionButton.isEnabled = false + + locationService?.startLocation(object : LocationHub.ILocationListener { + override fun onAMapLocationGet(aMapLocation: AMapLocation) { + drawTaskRoute(aMapLocation) + } + + override fun onAMapLocationError() { + "当前信号弱,无法定位".show(requireContext()) + } + }) } override fun onCancelClick() { @@ -235,11 +219,11 @@ requireContext().navigatePageTo( addAll( position.toString(), - newModel!!.id, - newModel!!.name, + newModel.id, + newModel.name, connectedDeviceCode, - latLngs.last.longitude.toString(), - latLngs.last.latitude.toString() + newModel.routes.last.longitude.toString(), + newModel.routes.last.latitude.toString() ) ) } @@ -247,6 +231,33 @@ } } + private fun drawTaskRoute(aMapLocation: AMapLocation) { + Log.d(kTag, "${aMapLocation.latitude}, ${aMapLocation.longitude}") + val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) + + //移动到指定经纬度 + val cameraPosition = CameraPosition(latLng, 15f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + + //stopInspectButton isEnabled,说明已经新建巡检任务,数据可以开始保存了 + if (binding.stopInspectButton.isEnabled) { + latLngList.add(latLng) + newModel.routes = latLngList + + //设置巡检起点 + if (newModel.startAddress.isNullOrEmpty()) { + newModel.startAddress = aMapLocation.address + } + + //巡检终点每次定位都覆盖,降低调用sdk频率 + newModel.endAddress = aMapLocation.address + + //绘制线 + aMap.addPolyline(PolylineOptions().addAll(newModel.routes).width(10f).color(Color.RED)) + } + } + private fun menuButtonEvent() { //结束巡检 binding.stopInspectButton.setOnClickListener { @@ -296,8 +307,6 @@ //关闭数据传送指令 bleManager.disconnectAllDevice() - latLngs.clear() - aMap.clear()//清除原来的路线 SaveKeyValues.removeKey(LocaleConstant.DEVICE_CODE) withContext(Dispatchers.Main) { binding.currentValueView.text = "--" @@ -539,42 +548,51 @@ * * 如果保存到本地,则需要设置标识位,然后finish当前页面并提示 * */ - if (newModel == null) { - "保存失败".show(requireContext()) - return - } - LoadingDialogHub.show(requireActivity(), "数据保存中,请稍后...") + val routes = newModel.routes // 保存巡检位置点 lifecycleScope.launch(Dispatchers.Main) { withContext(Dispatchers.IO) { - for (i in 0 until latLngs.size) { - newModel!!.routes.add(latLngs[i]) - - DataBaseManager.get.addInspectionRoute(newModel!!.id, latLngs[i]) + for (i in 0 until routes.size) { + DataBaseManager.get.addInspectionRoute(newModel.id, routes[i]) } - DataBaseManager.get.addInspection( - inspectionId = newModel!!.id, - deviceCode = connectedDeviceCode, - inspectionName = newModel!!.name, - startTime = newModel!!.startTime, - endTime = System.currentTimeMillis().timestampToCompleteDate(), - date = newModel!!.date, - startLng = latLngs.first.longitude, - startLat = latLngs.first.latitude, - newModel!!.startAddress, - endLng = latLngs.last.longitude, - endLat = latLngs.last.latitude, - newModel!!.endAddress, - routes = newModel!!.routes - ) + try { + val first = routes.first + val last = routes.last + DataBaseManager.get.addInspection( + inspectionId = newModel.id, + deviceCode = connectedDeviceCode, + inspectionName = newModel.name, + startTime = newModel.startTime, + endTime = System.currentTimeMillis().timestampToCompleteDate(), + date = newModel.date, + startLng = first.longitude, + startLat = first.latitude, + startAddress = newModel.startAddress, + endLng = last.longitude, + endLat = last.latitude, + endAddress = newModel.endAddress, + routes = newModel.routes + ) + } catch (e: NoSuchElementException) { + e.printStackTrace() + withContext(Dispatchers.Main) { + "无定位数据,保存任务失败".show(requireContext()) + } + } } LoadingDialogHub.dismiss() + //清空newModel + newModel.clearCache() + + //停止定位 + locationService?.stopLocation() + //结束任务就清空轨迹 - latLngs.clear() + latLngList.clear() aMap.clear() //按钮状态 @@ -611,10 +629,6 @@ //如果连续超过10个报警,自动生成报警事件 alarmCount++ if (alarmCount >= 10) { - if (newModel == null) { - "没有巡检任务,无法自动记录报警".show(requireContext()) - return - } generateAlarmTask(dataModel.maxPotency) } } @@ -635,13 +649,13 @@ DataBaseManager.get.addEvent( taskId = UUID.randomUUID().toString(), - inspectionId = newModel!!.id, + inspectionId = newModel.id, deviceCode = connectedDeviceCode, - eventTitle = newModel!!.name, + eventTitle = newModel.name, createTime = System.currentTimeMillis().timestampToCompleteDate(), type = "报警事件", - lng = latLngs.last.longitude, - lat = latLngs.last.latitude, + lng = newModel.routes.last.longitude, + lat = newModel.routes.last.latitude, data = maxValue, images = "", description = "自动报警记录" @@ -671,11 +685,28 @@ } //设置标题和时间 - if (newModel == null) { - return + binding.inspectNameView.text = newModel.name + binding.inspectTimeView.text = newModel.startTime + + //绑定定位服务 + Intent(requireContext(), LocationService::class.java).also { + requireContext().bindService(it, serviceConnection, Context.BIND_AUTO_CREATE) } - binding.inspectNameView.text = newModel!!.name - binding.inspectTimeView.text = newModel!!.startTime + } + + private var locationService: LocationService? = null + + private val serviceConnection = object : ServiceConnection { + override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) { + if (iBinder is LocationService.ServiceBinder) { + locationService = iBinder.getLocationService() + Log.d(kTag, "onServiceConnected: ") + } + } + + override fun onServiceDisconnected(name: ComponentName?) { + "定位服务已断开".show(requireContext()) + } } override fun onPause() { diff --git a/app/src/main/java/com/casic/birmm/inspect/utils/DataBaseManager.kt b/app/src/main/java/com/casic/birmm/inspect/utils/DataBaseManager.kt index 3a2cac1..268f37b 100644 --- a/app/src/main/java/com/casic/birmm/inspect/utils/DataBaseManager.kt +++ b/app/src/main/java/com/casic/birmm/inspect/utils/DataBaseManager.kt @@ -12,6 +12,7 @@ import com.casic.birmm.inspect.greendao.TaskEventLocalBeanDao import com.casic.birmm.inspect.single.fragment.QueryEventFragment import com.casic.birmm.inspect.single.fragment.QueryInspectionFragment +import java.util.LinkedList class DataBaseManager private constructor() { @@ -44,7 +45,7 @@ endLng: Double, endLat: Double, endAddress: String, - routes: ArrayList + routes: LinkedList ) { val bean = InspectionLocalBean() bean.inspectionId = inspectionId diff --git a/app/src/main/java/com/casic/birmm/inspect/utils/LocationHub.kt b/app/src/main/java/com/casic/birmm/inspect/utils/LocationHub.kt index 11be914..5e12297 100644 --- a/app/src/main/java/com/casic/birmm/inspect/utils/LocationHub.kt +++ b/app/src/main/java/com/casic/birmm/inspect/utils/LocationHub.kt @@ -5,57 +5,54 @@ import com.amap.api.location.AMapLocation import com.amap.api.location.AMapLocationClient import com.amap.api.location.AMapLocationClientOption +import com.amap.api.location.AMapLocationListener class LocationHub private constructor() { private val kTag = "LocationHub" companion object { - //Kotlin委托模式双重锁单例 - val get: LocationHub by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { + val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { LocationHub() } } private val locationOption = AMapLocationClientOption() - private lateinit var locationClient: AMapLocationClient + private var locationClient: AMapLocationClient? = null init { //设置定位模式为高精度模式,AMapLocationMode.Battery_Saving为低功耗模式,AMapLocationMode.Device_Sensors是仅设备模式 locationOption.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy - locationOption.interval = 10 * 1000 //10s定位一次 locationOption.isNeedAddress = true //设置是否返回地址信息(默认返回地址信息) - locationOption.isLocationCacheEnable = true //可选,设置是否使用缓存定位,默认为true } /** * 高德sdk定位 */ - fun getLocationByAMap(context: Context?, listener: ILocationListener) { + fun getLocationByAMap(context: Context, listener: AMapLocationListener) { locationClient = AMapLocationClient(context) //给定位客户端对象设置定位参数 - locationClient.setLocationOption(locationOption) + locationClient?.setLocationOption(locationOption) //设置定位回调监听 - locationClient.setLocationListener { aMapLocation -> - if (aMapLocation != null) { - if (aMapLocation.errorCode == 0) { - listener.onAMapLocationGet(aMapLocation) + locationClient?.setLocationListener { + if (it != null) { + if (it.errorCode == 0) { + listener.onLocationChanged(it) } else { - Log.e( - kTag, - "ErrCode: ${aMapLocation.errorCode}, errInfo: ${aMapLocation.errorInfo}" - ) + Log.e(kTag, "errCode: ${it.errorCode}, errInfo: ${it.errorInfo}") } } } //启动定位 - locationClient.startLocation() + locationClient?.startLocation() } fun stopLocation() { - locationClient.stopLocation()//停止定位 + locationClient?.stopLocation()//停止定位 } interface ILocationListener { - fun onAMapLocationGet(aMapLocation: AMapLocation?) //高德定位数据 + fun onAMapLocationGet(aMapLocation: AMapLocation) //高德定位数据 + + fun onAMapLocationError() } } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_event_detail.xml b/app/src/main/res/layout/activity_event_detail.xml index d8dc39e..aa8cdf3 100644 --- a/app/src/main/res/layout/activity_event_detail.xml +++ b/app/src/main/res/layout/activity_event_detail.xml @@ -97,7 +97,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" - android:text="最大泄露数值" + android:text="最大泄露数值(ppm · m)" android:textColor="@color/black" android:textSize="@dimen/sp_16" /> diff --git a/app/src/main/res/layout/activity_new_event.xml b/app/src/main/res/layout/activity_new_event.xml index 3bac2d9..c910137 100644 --- a/app/src/main/res/layout/activity_new_event.xml +++ b/app/src/main/res/layout/activity_new_event.xml @@ -94,7 +94,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" - android:text="最大泄露数值" + android:text="最大泄露数值(ppm · m)" android:textColor="@color/black" android:textSize="@dimen/sp_16" /> diff --git a/app/build.gradle b/app/build.gradle index 9d0f82e..feb5ca9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -20,8 +20,8 @@ applicationId "com.casic.birmm.inspect" minSdkVersion 23 targetSdkVersion 33 - versionCode 1071 - versionName "1.0.7.1" + versionCode 1072 + versionName "1.0.7.2" } buildTypes { diff --git a/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt b/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt index 30b8f28..12c92e6 100644 --- a/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt @@ -1,12 +1,5 @@ package com.casic.birmm.inspect.extensions -import com.amap.api.maps.model.LatLng -import com.amap.api.services.core.LatLonPoint -import com.amap.api.services.route.DistanceSearch -import com.casic.birmm.inspect.base.BaseApplication -import com.casic.birmm.inspect.callback.OnDistanceSearchListener -import java.text.DecimalFormat - /** * ArrayList扩展方法 */ @@ -32,39 +25,4 @@ result.add(it) } return result -} - -private val distanceSearch by lazy { DistanceSearch(BaseApplication.get()) } -private val distanceQuery by lazy { DistanceSearch.DistanceQuery() } -private val decimalFormat by lazy { DecimalFormat("#.##") } - -fun ArrayList.calculateDistance(listener: OnDistanceSearchListener) { - if (this.isEmpty()) { - listener.onDistanceSearched("0.00") - } - - val last = this.last() - val dest = LatLonPoint(last.latitude, last.longitude) - - //去掉最后一个点 - this.removeLast() - val latLonPoints: ArrayList = ArrayList() - this.forEach { - latLonPoints.add(LatLonPoint(it.latitude, it.longitude)) - } - - distanceQuery.origins = latLonPoints - distanceQuery.destination = dest - distanceQuery.type = DistanceSearch.TYPE_WALK_DISTANCE - distanceSearch.calculateRouteDistanceAsyn(distanceQuery) - distanceSearch.setDistanceSearchListener { distanceResult, errorCode -> - if (errorCode == 1000) { - //DistanceResult返回的是单位是米 - val temp = distanceResult.distanceResults[0].distance - val distance = temp / 1000 - listener.onDistanceSearched(decimalFormat.format(distance)) - } else { - listener.onDistanceSearched("0.00") - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt index d5b1bc0..13b752f 100644 --- a/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt +++ b/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt @@ -2,9 +2,14 @@ import android.bluetooth.BluetoothGatt import android.bluetooth.BluetoothGattCharacteristic +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.ServiceConnection import android.graphics.Color import android.os.Bundle import android.os.Handler +import android.os.IBinder import android.os.Message import android.os.Vibrator import android.util.Log @@ -33,6 +38,7 @@ import com.casic.birmm.inspect.extensions.toDeviceCode import com.casic.birmm.inspect.extensions.toDeviceModel import com.casic.birmm.inspect.model.NewInspectionModel +import com.casic.birmm.inspect.service.LocationService import com.casic.birmm.inspect.utils.LocaleConstant import com.casic.birmm.inspect.utils.LocationHub import com.casic.birmm.inspect.utils.SoundPoolHelper @@ -99,7 +105,8 @@ private val kTag = "HomePageFragment" private val bleManager by lazy { BleManager.getInstance() } - private val latLngs = LinkedList() + private val newModel by lazy { NewInspectionModel() }//新建巡检数据结构模型 + private val latLngList by lazy { LinkedList() } private lateinit var userName: String private lateinit var eventViewModel: EventViewModel private lateinit var inspectionViewModel: InspectionViewModel @@ -108,7 +115,6 @@ private lateinit var writeUuid: String private lateinit var notifyUuid: String private var vibrator: Vibrator? = null - private var newModel: NewInspectionModel? = null//新建巡检数据结构模型 private var connectedDevice: BleDevice? = null private var isGeneratingTask = false private var alarmCount = 0 @@ -147,49 +153,19 @@ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isCompassEnabled = true uiSettings.isZoomControlsEnabled = true + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 //显示定位小蓝点 val locationStyle = MyLocationStyle() - locationStyle.showMyLocation(true)//设置是否显示定位小蓝点 + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + //定位、移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE) aMap.myLocationStyle = locationStyle aMap.isMyLocationEnabled = true aMap.mapType = AMap.MAP_TYPE_NORMAL - LocationHub.get.getLocationByAMap(requireContext(), object : LocationHub.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - "当前信号弱,无法定位".show(requireContext()) - return - } - - val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) - - //移动到指定经纬度 - val cameraPosition = CameraPosition(latLng, 16f, 0f, 0f) - val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) - aMap.animateCamera(cameraUpdate, 1500, null) - - //newInspectionModel已完成初始化,说明已经新建巡检任务,数据可以开始保存了 - if (newModel != null) { - //设置巡检起点 - if (newModel!!.startAddress.isEmpty()) { - newModel!!.startAddress = aMapLocation.address - } - - //巡检终点每次定位都覆盖,降低调用sdk频率 - newModel!!.endAddress = aMapLocation.address - - latLngs.add(latLng) - - //绘制线 - aMap.addPolyline( - PolylineOptions().addAll(latLngs).width(10f).color(Color.RED) - ) - } - } - }) - //UserName userName = SaveKeyValues.getValue(LocaleConstant.USER_NAME, "").toString() @@ -217,8 +193,11 @@ is LoadState.Success -> { LoadingDialogHub.dismiss() + //清空newModel + newModel.clearCache() + //结束任务就清空轨迹 - latLngs.clear() + latLngList.clear() aMap.clear() //按钮状态 @@ -248,16 +227,25 @@ binding.inspectNameView.text = value binding.inspectTimeView.text = startTime - newModel = NewInspectionModel( - currentTimeMillis.id(), value, - startTime, "", currentTimeMillis.timestampToDate(), - 0.0, 0.0, "", 0.0, 0.0, "", - ArrayList(), userName - ) + newModel.id = currentTimeMillis.id() + newModel.name = value + newModel.startTime = startTime + newModel.date = currentTimeMillis.timestampToDate() + newModel.user = userName //按钮状态 binding.stopInspectButton.isEnabled = true binding.addInspectionButton.isEnabled = false + + locationService?.startLocation(object : LocationHub.ILocationListener { + override fun onAMapLocationGet(aMapLocation: AMapLocation) { + drawTaskRoute(aMapLocation) + } + + override fun onAMapLocationError() { + "当前信号弱,无法定位".show(requireContext()) + } + }) } override fun onCancelClick() { @@ -284,11 +272,11 @@ requireContext().navigatePageTo( addAll( position.toString(), - newModel!!.id, - newModel!!.name, + newModel.id, + newModel.name, connectedDeviceCode, - latLngs.last.longitude.toString(), - latLngs.last.latitude.toString() + newModel.routes.last.longitude.toString(), + newModel.routes.last.latitude.toString() ) ) } @@ -296,6 +284,33 @@ } } + private fun drawTaskRoute(aMapLocation: AMapLocation) { + Log.d(kTag, "${aMapLocation.latitude}, ${aMapLocation.longitude}") + val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) + + //移动到指定经纬度 + val cameraPosition = CameraPosition(latLng, 15f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + + //stopInspectButton isEnabled,说明已经新建巡检任务,数据可以开始保存了 + if (binding.stopInspectButton.isEnabled) { + latLngList.add(latLng) + newModel.routes = latLngList + + //设置巡检起点 + if (newModel.startAddress.isNullOrEmpty()) { + newModel.startAddress = aMapLocation.address + } + + //巡检终点每次定位都覆盖,降低调用sdk频率 + newModel.endAddress = aMapLocation.address + + //绘制线 + aMap.addPolyline(PolylineOptions().addAll(newModel.routes).width(10f).color(Color.RED)) + } + } + private fun menuButtonEvent() { //结束巡检 binding.stopInspectButton.setOnClickListener { @@ -345,8 +360,6 @@ //关闭数据传送指令 bleManager.disconnectAllDevice() - latLngs.clear() - aMap.clear()//清除原来的路线 SaveKeyValues.removeKey(LocaleConstant.DEVICE_CODE) withContext(Dispatchers.Main) { binding.currentValueView.text = "--" @@ -588,44 +601,41 @@ * * 如果保存到本地,则需要设置标识位,然后finish当前页面并提示 * */ - if (newModel == null) { - "保存失败".show(requireContext()) - return - } - - // 上传巡检位置点 - for (i in 0 until latLngs.size) { - newModel!!.routes.add(latLngs[i]) + val routes = newModel.routes + for (i in 0 until routes.size) { //上传点位 routeViewModel.uploadRoutePoint( - newModel!!.id, - latLngs[i], - System.currentTimeMillis().timestampToCompleteDate() + newModel.id, routes[i], System.currentTimeMillis().timestampToCompleteDate() ) } - val first = latLngs.first - val last = latLngs.last - newModel!!.routes.calculateDistance(object : OnDistanceSearchListener { - override fun onDistanceSearched(distance: String) { - inspectionViewModel.addInspection( - id = newModel!!.id, - deviceCode = connectedDeviceCode, - name = newModel!!.name, - startTime = newModel!!.startTime, - endTime = System.currentTimeMillis().timestampToCompleteDate(), - date = newModel!!.date, - startLng = first.longitude, - startLat = first.latitude, - newModel!!.startAddress, - endLng = last.longitude, - endLat = last.latitude, - newModel!!.endAddress, - distance, - user = userName - ) - } - }) + try { + val first = routes.first + val last = routes.last + routes.calculateDistance(object : OnDistanceSearchListener { + override fun onDistanceSearched(distance: String) { + inspectionViewModel.addInspection( + id = newModel.id, + deviceCode = connectedDeviceCode, + name = newModel.name, + startTime = newModel.startTime, + endTime = System.currentTimeMillis().timestampToCompleteDate(), + date = newModel.date, + startLng = first.longitude, + startLat = first.latitude, + startAddress = newModel.startAddress, + endLng = last.longitude, + endLat = last.latitude, + endAddress = newModel.endAddress, + distance, + user = userName + ) + } + }) + } catch (e: NoSuchElementException) { + e.printStackTrace() + "无定位数据,保存任务失败".show(requireContext()) + } } /** @@ -657,10 +667,6 @@ //如果连续超过10个报警,自动生成报警事件 alarmCount++ if (alarmCount >= 10) { - if (newModel == null) { - "没有巡检任务,无法自动记录报警".show(requireContext()) - return - } generateAlarmTask(dataModel.maxPotency) } } @@ -680,12 +686,12 @@ eventViewModel.addEventTask( id = UUID.randomUUID().toString(), - inspectionId = newModel!!.id, - name = newModel!!.name, + inspectionId = newModel.id, + name = newModel.name, createTime = System.currentTimeMillis().timestampToCompleteDate(), type = "报警事件", - lng = latLngs.last.longitude, - lat = latLngs.last.latitude, + lng = newModel.routes.last.longitude, + lat = newModel.routes.last.latitude, data = maxValue, images = "", description = "自动报警记录", @@ -713,11 +719,28 @@ } //设置标题和时间 - if (newModel == null) { - return + binding.inspectNameView.text = newModel.name + binding.inspectTimeView.text = newModel.startTime + + //绑定定位服务 + Intent(requireContext(), LocationService::class.java).also { + requireContext().bindService(it, serviceConnection, Context.BIND_AUTO_CREATE) } - binding.inspectNameView.text = newModel!!.name - binding.inspectTimeView.text = newModel!!.startTime + } + + private var locationService: LocationService? = null + + private val serviceConnection = object : ServiceConnection { + override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) { + if (iBinder is LocationService.ServiceBinder) { + locationService = iBinder.getLocationService() + Log.d(kTag, "onServiceConnected: ") + } + } + + override fun onServiceDisconnected(name: ComponentName?) { + "定位服务已断开".show(requireContext()) + } } override fun onPause() { diff --git a/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.java b/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.java new file mode 100644 index 0000000..f09810f --- /dev/null +++ b/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.java @@ -0,0 +1,141 @@ +package com.casic.birmm.inspect.model; + +import com.amap.api.maps.model.LatLng; + +import java.util.LinkedList; + +public class NewInspectionModel { + private String id; + private String name; + private String startTime; + private String endTime; + private String date; + private String startLng; + private String startLat; + private String startAddress; + private String endLng; + private String endLat; + private String endAddress; + private LinkedList routes; + private String user; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + + public String getEndTime() { + return endTime; + } + + public void setEndTime(String endTime) { + this.endTime = endTime; + } + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } + + public String getStartLng() { + return startLng; + } + + public void setStartLng(String startLng) { + this.startLng = startLng; + } + + public String getStartLat() { + return startLat; + } + + public void setStartLat(String startLat) { + this.startLat = startLat; + } + + public String getStartAddress() { + return startAddress; + } + + public void setStartAddress(String startAddress) { + this.startAddress = startAddress; + } + + public String getEndLng() { + return endLng; + } + + public void setEndLng(String endLng) { + this.endLng = endLng; + } + + public String getEndLat() { + return endLat; + } + + public void setEndLat(String endLat) { + this.endLat = endLat; + } + + public String getEndAddress() { + return endAddress; + } + + public void setEndAddress(String endAddress) { + this.endAddress = endAddress; + } + + public LinkedList getRoutes() { + return routes; + } + + public void setRoutes(LinkedList routes) { + this.routes = routes; + } + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public void clearCache() { + this.id = ""; + this.name = ""; + this.startTime = ""; + this.endTime = ""; + this.date = ""; + this.startLng = ""; + this.startLat = ""; + this.startAddress = ""; + this.endLng = ""; + this.endLat = ""; + this.endAddress = ""; + this.routes.clear(); + this.user = ""; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.kt b/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.kt deleted file mode 100644 index f08334a..0000000 --- a/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.birmm.inspect.model - -import com.amap.api.maps.model.LatLng - -data class NewInspectionModel( - var id: String, - var name: String, - var startTime: String, - var endTime: String, - var date: String, - var startLng: Double, - var startLat: Double, - var startAddress: String, - var endLng: Double, - var endLat: Double, - var endAddress: String, - var routes: ArrayList, - var user: String -) \ No newline at end of file diff --git a/app/src/main/java/com/casic/birmm/inspect/single/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/birmm/inspect/single/fragment/HomePageFragment.kt index 031525e..76c7846 100644 --- a/app/src/main/java/com/casic/birmm/inspect/single/fragment/HomePageFragment.kt +++ b/app/src/main/java/com/casic/birmm/inspect/single/fragment/HomePageFragment.kt @@ -2,9 +2,14 @@ import android.bluetooth.BluetoothGatt import android.bluetooth.BluetoothGattCharacteristic +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.ServiceConnection import android.graphics.Color import android.os.Bundle import android.os.Handler +import android.os.IBinder import android.os.Message import android.os.Vibrator import android.util.Log @@ -30,6 +35,7 @@ import com.casic.birmm.inspect.extensions.toDeviceCode import com.casic.birmm.inspect.extensions.toDeviceModel import com.casic.birmm.inspect.model.NewInspectionModel +import com.casic.birmm.inspect.service.LocationService import com.casic.birmm.inspect.single.view.NewEventActivity import com.casic.birmm.inspect.utils.DataBaseManager import com.casic.birmm.inspect.utils.LocaleConstant @@ -93,12 +99,12 @@ private val kTag = "HomePageFragment" private val bleManager by lazy { BleManager.getInstance() } - private val latLngs = LinkedList() + private val newModel by lazy { NewInspectionModel() }//新建巡检数据结构模型 + private val latLngList by lazy { LinkedList() } private lateinit var aMap: AMap private lateinit var writeUuid: String private lateinit var notifyUuid: String private var vibrator: Vibrator? = null - private var newModel: NewInspectionModel? = null//新建巡检数据结构模型 private var connectedDevice: BleDevice? = null private var isGeneratingTask = false private var alarmCount = 0 @@ -136,48 +142,17 @@ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isCompassEnabled = true uiSettings.isZoomControlsEnabled = true + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 //显示定位小蓝点 val locationStyle = MyLocationStyle() - locationStyle.showMyLocation(true)//设置是否显示定位小蓝点 + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + //定位、移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE) aMap.myLocationStyle = locationStyle aMap.isMyLocationEnabled = true - aMap.mapType = AMap.MAP_TYPE_NORMAL - - LocationHub.get.getLocationByAMap(requireContext(), object : LocationHub.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - "当前信号弱,无法定位".show(requireContext()) - return - } - - val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) - - //移动到指定经纬度 - val cameraPosition = CameraPosition(latLng, 16f, 0f, 0f) - val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) - aMap.animateCamera(cameraUpdate, 1500, null) - - //newInspectionModel已完成初始化,说明已经新建巡检任务,数据可以开始保存了 - if (newModel != null) { - //设置巡检起点 - if (newModel!!.startAddress.isEmpty()) { - newModel!!.startAddress = aMapLocation.address - } - - //巡检终点每次定位都覆盖,降低调用sdk频率 - newModel!!.endAddress = aMapLocation.address - - latLngs.add(latLng) - - //绘制线 - aMap.addPolyline( - PolylineOptions().addAll(latLngs).width(10f).color(Color.RED) - ) - } - } - }) } override fun observeRequestState() { @@ -199,16 +174,25 @@ binding.inspectNameView.text = value binding.inspectTimeView.text = startTime - newModel = NewInspectionModel( - currentTimeMillis.id(), value, - startTime, "", currentTimeMillis.timestampToDate(), - 0.0, 0.0, "", 0.0, 0.0, "", - ArrayList(), "智巡宝" - ) + newModel.id = currentTimeMillis.id() + newModel.name = value + newModel.startTime = startTime + newModel.date = currentTimeMillis.timestampToDate() + newModel.user = "智巡宝" //按钮状态 binding.stopInspectButton.isEnabled = true binding.addInspectionButton.isEnabled = false + + locationService?.startLocation(object : LocationHub.ILocationListener { + override fun onAMapLocationGet(aMapLocation: AMapLocation) { + drawTaskRoute(aMapLocation) + } + + override fun onAMapLocationError() { + "当前信号弱,无法定位".show(requireContext()) + } + }) } override fun onCancelClick() { @@ -235,11 +219,11 @@ requireContext().navigatePageTo( addAll( position.toString(), - newModel!!.id, - newModel!!.name, + newModel.id, + newModel.name, connectedDeviceCode, - latLngs.last.longitude.toString(), - latLngs.last.latitude.toString() + newModel.routes.last.longitude.toString(), + newModel.routes.last.latitude.toString() ) ) } @@ -247,6 +231,33 @@ } } + private fun drawTaskRoute(aMapLocation: AMapLocation) { + Log.d(kTag, "${aMapLocation.latitude}, ${aMapLocation.longitude}") + val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) + + //移动到指定经纬度 + val cameraPosition = CameraPosition(latLng, 15f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + + //stopInspectButton isEnabled,说明已经新建巡检任务,数据可以开始保存了 + if (binding.stopInspectButton.isEnabled) { + latLngList.add(latLng) + newModel.routes = latLngList + + //设置巡检起点 + if (newModel.startAddress.isNullOrEmpty()) { + newModel.startAddress = aMapLocation.address + } + + //巡检终点每次定位都覆盖,降低调用sdk频率 + newModel.endAddress = aMapLocation.address + + //绘制线 + aMap.addPolyline(PolylineOptions().addAll(newModel.routes).width(10f).color(Color.RED)) + } + } + private fun menuButtonEvent() { //结束巡检 binding.stopInspectButton.setOnClickListener { @@ -296,8 +307,6 @@ //关闭数据传送指令 bleManager.disconnectAllDevice() - latLngs.clear() - aMap.clear()//清除原来的路线 SaveKeyValues.removeKey(LocaleConstant.DEVICE_CODE) withContext(Dispatchers.Main) { binding.currentValueView.text = "--" @@ -539,42 +548,51 @@ * * 如果保存到本地,则需要设置标识位,然后finish当前页面并提示 * */ - if (newModel == null) { - "保存失败".show(requireContext()) - return - } - LoadingDialogHub.show(requireActivity(), "数据保存中,请稍后...") + val routes = newModel.routes // 保存巡检位置点 lifecycleScope.launch(Dispatchers.Main) { withContext(Dispatchers.IO) { - for (i in 0 until latLngs.size) { - newModel!!.routes.add(latLngs[i]) - - DataBaseManager.get.addInspectionRoute(newModel!!.id, latLngs[i]) + for (i in 0 until routes.size) { + DataBaseManager.get.addInspectionRoute(newModel.id, routes[i]) } - DataBaseManager.get.addInspection( - inspectionId = newModel!!.id, - deviceCode = connectedDeviceCode, - inspectionName = newModel!!.name, - startTime = newModel!!.startTime, - endTime = System.currentTimeMillis().timestampToCompleteDate(), - date = newModel!!.date, - startLng = latLngs.first.longitude, - startLat = latLngs.first.latitude, - newModel!!.startAddress, - endLng = latLngs.last.longitude, - endLat = latLngs.last.latitude, - newModel!!.endAddress, - routes = newModel!!.routes - ) + try { + val first = routes.first + val last = routes.last + DataBaseManager.get.addInspection( + inspectionId = newModel.id, + deviceCode = connectedDeviceCode, + inspectionName = newModel.name, + startTime = newModel.startTime, + endTime = System.currentTimeMillis().timestampToCompleteDate(), + date = newModel.date, + startLng = first.longitude, + startLat = first.latitude, + startAddress = newModel.startAddress, + endLng = last.longitude, + endLat = last.latitude, + endAddress = newModel.endAddress, + routes = newModel.routes + ) + } catch (e: NoSuchElementException) { + e.printStackTrace() + withContext(Dispatchers.Main) { + "无定位数据,保存任务失败".show(requireContext()) + } + } } LoadingDialogHub.dismiss() + //清空newModel + newModel.clearCache() + + //停止定位 + locationService?.stopLocation() + //结束任务就清空轨迹 - latLngs.clear() + latLngList.clear() aMap.clear() //按钮状态 @@ -611,10 +629,6 @@ //如果连续超过10个报警,自动生成报警事件 alarmCount++ if (alarmCount >= 10) { - if (newModel == null) { - "没有巡检任务,无法自动记录报警".show(requireContext()) - return - } generateAlarmTask(dataModel.maxPotency) } } @@ -635,13 +649,13 @@ DataBaseManager.get.addEvent( taskId = UUID.randomUUID().toString(), - inspectionId = newModel!!.id, + inspectionId = newModel.id, deviceCode = connectedDeviceCode, - eventTitle = newModel!!.name, + eventTitle = newModel.name, createTime = System.currentTimeMillis().timestampToCompleteDate(), type = "报警事件", - lng = latLngs.last.longitude, - lat = latLngs.last.latitude, + lng = newModel.routes.last.longitude, + lat = newModel.routes.last.latitude, data = maxValue, images = "", description = "自动报警记录" @@ -671,11 +685,28 @@ } //设置标题和时间 - if (newModel == null) { - return + binding.inspectNameView.text = newModel.name + binding.inspectTimeView.text = newModel.startTime + + //绑定定位服务 + Intent(requireContext(), LocationService::class.java).also { + requireContext().bindService(it, serviceConnection, Context.BIND_AUTO_CREATE) } - binding.inspectNameView.text = newModel!!.name - binding.inspectTimeView.text = newModel!!.startTime + } + + private var locationService: LocationService? = null + + private val serviceConnection = object : ServiceConnection { + override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) { + if (iBinder is LocationService.ServiceBinder) { + locationService = iBinder.getLocationService() + Log.d(kTag, "onServiceConnected: ") + } + } + + override fun onServiceDisconnected(name: ComponentName?) { + "定位服务已断开".show(requireContext()) + } } override fun onPause() { diff --git a/app/src/main/java/com/casic/birmm/inspect/utils/DataBaseManager.kt b/app/src/main/java/com/casic/birmm/inspect/utils/DataBaseManager.kt index 3a2cac1..268f37b 100644 --- a/app/src/main/java/com/casic/birmm/inspect/utils/DataBaseManager.kt +++ b/app/src/main/java/com/casic/birmm/inspect/utils/DataBaseManager.kt @@ -12,6 +12,7 @@ import com.casic.birmm.inspect.greendao.TaskEventLocalBeanDao import com.casic.birmm.inspect.single.fragment.QueryEventFragment import com.casic.birmm.inspect.single.fragment.QueryInspectionFragment +import java.util.LinkedList class DataBaseManager private constructor() { @@ -44,7 +45,7 @@ endLng: Double, endLat: Double, endAddress: String, - routes: ArrayList + routes: LinkedList ) { val bean = InspectionLocalBean() bean.inspectionId = inspectionId diff --git a/app/src/main/java/com/casic/birmm/inspect/utils/LocationHub.kt b/app/src/main/java/com/casic/birmm/inspect/utils/LocationHub.kt index 11be914..5e12297 100644 --- a/app/src/main/java/com/casic/birmm/inspect/utils/LocationHub.kt +++ b/app/src/main/java/com/casic/birmm/inspect/utils/LocationHub.kt @@ -5,57 +5,54 @@ import com.amap.api.location.AMapLocation import com.amap.api.location.AMapLocationClient import com.amap.api.location.AMapLocationClientOption +import com.amap.api.location.AMapLocationListener class LocationHub private constructor() { private val kTag = "LocationHub" companion object { - //Kotlin委托模式双重锁单例 - val get: LocationHub by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { + val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { LocationHub() } } private val locationOption = AMapLocationClientOption() - private lateinit var locationClient: AMapLocationClient + private var locationClient: AMapLocationClient? = null init { //设置定位模式为高精度模式,AMapLocationMode.Battery_Saving为低功耗模式,AMapLocationMode.Device_Sensors是仅设备模式 locationOption.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy - locationOption.interval = 10 * 1000 //10s定位一次 locationOption.isNeedAddress = true //设置是否返回地址信息(默认返回地址信息) - locationOption.isLocationCacheEnable = true //可选,设置是否使用缓存定位,默认为true } /** * 高德sdk定位 */ - fun getLocationByAMap(context: Context?, listener: ILocationListener) { + fun getLocationByAMap(context: Context, listener: AMapLocationListener) { locationClient = AMapLocationClient(context) //给定位客户端对象设置定位参数 - locationClient.setLocationOption(locationOption) + locationClient?.setLocationOption(locationOption) //设置定位回调监听 - locationClient.setLocationListener { aMapLocation -> - if (aMapLocation != null) { - if (aMapLocation.errorCode == 0) { - listener.onAMapLocationGet(aMapLocation) + locationClient?.setLocationListener { + if (it != null) { + if (it.errorCode == 0) { + listener.onLocationChanged(it) } else { - Log.e( - kTag, - "ErrCode: ${aMapLocation.errorCode}, errInfo: ${aMapLocation.errorInfo}" - ) + Log.e(kTag, "errCode: ${it.errorCode}, errInfo: ${it.errorInfo}") } } } //启动定位 - locationClient.startLocation() + locationClient?.startLocation() } fun stopLocation() { - locationClient.stopLocation()//停止定位 + locationClient?.stopLocation()//停止定位 } interface ILocationListener { - fun onAMapLocationGet(aMapLocation: AMapLocation?) //高德定位数据 + fun onAMapLocationGet(aMapLocation: AMapLocation) //高德定位数据 + + fun onAMapLocationError() } } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_event_detail.xml b/app/src/main/res/layout/activity_event_detail.xml index d8dc39e..aa8cdf3 100644 --- a/app/src/main/res/layout/activity_event_detail.xml +++ b/app/src/main/res/layout/activity_event_detail.xml @@ -97,7 +97,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" - android:text="最大泄露数值" + android:text="最大泄露数值(ppm · m)" android:textColor="@color/black" android:textSize="@dimen/sp_16" /> diff --git a/app/src/main/res/layout/activity_new_event.xml b/app/src/main/res/layout/activity_new_event.xml index 3bac2d9..c910137 100644 --- a/app/src/main/res/layout/activity_new_event.xml +++ b/app/src/main/res/layout/activity_new_event.xml @@ -94,7 +94,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" - android:text="最大泄露数值" + android:text="最大泄露数值(ppm · m)" android:textColor="@color/black" android:textSize="@dimen/sp_16" /> diff --git a/app/src/main/res/layout/single_activity_event_detail.xml b/app/src/main/res/layout/single_activity_event_detail.xml index d8dc39e..aa8cdf3 100644 --- a/app/src/main/res/layout/single_activity_event_detail.xml +++ b/app/src/main/res/layout/single_activity_event_detail.xml @@ -97,7 +97,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" - android:text="最大泄露数值" + android:text="最大泄露数值(ppm · m)" android:textColor="@color/black" android:textSize="@dimen/sp_16" /> diff --git a/app/build.gradle b/app/build.gradle index 9d0f82e..feb5ca9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -20,8 +20,8 @@ applicationId "com.casic.birmm.inspect" minSdkVersion 23 targetSdkVersion 33 - versionCode 1071 - versionName "1.0.7.1" + versionCode 1072 + versionName "1.0.7.2" } buildTypes { diff --git a/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt b/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt index 30b8f28..12c92e6 100644 --- a/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt +++ b/app/src/main/java/com/casic/birmm/inspect/extensions/ArrayList.kt @@ -1,12 +1,5 @@ package com.casic.birmm.inspect.extensions -import com.amap.api.maps.model.LatLng -import com.amap.api.services.core.LatLonPoint -import com.amap.api.services.route.DistanceSearch -import com.casic.birmm.inspect.base.BaseApplication -import com.casic.birmm.inspect.callback.OnDistanceSearchListener -import java.text.DecimalFormat - /** * ArrayList扩展方法 */ @@ -32,39 +25,4 @@ result.add(it) } return result -} - -private val distanceSearch by lazy { DistanceSearch(BaseApplication.get()) } -private val distanceQuery by lazy { DistanceSearch.DistanceQuery() } -private val decimalFormat by lazy { DecimalFormat("#.##") } - -fun ArrayList.calculateDistance(listener: OnDistanceSearchListener) { - if (this.isEmpty()) { - listener.onDistanceSearched("0.00") - } - - val last = this.last() - val dest = LatLonPoint(last.latitude, last.longitude) - - //去掉最后一个点 - this.removeLast() - val latLonPoints: ArrayList = ArrayList() - this.forEach { - latLonPoints.add(LatLonPoint(it.latitude, it.longitude)) - } - - distanceQuery.origins = latLonPoints - distanceQuery.destination = dest - distanceQuery.type = DistanceSearch.TYPE_WALK_DISTANCE - distanceSearch.calculateRouteDistanceAsyn(distanceQuery) - distanceSearch.setDistanceSearchListener { distanceResult, errorCode -> - if (errorCode == 1000) { - //DistanceResult返回的是单位是米 - val temp = distanceResult.distanceResults[0].distance - val distance = temp / 1000 - listener.onDistanceSearched(decimalFormat.format(distance)) - } else { - listener.onDistanceSearched("0.00") - } - } } \ No newline at end of file diff --git a/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt index d5b1bc0..13b752f 100644 --- a/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt +++ b/app/src/main/java/com/casic/birmm/inspect/fragment/HomePageFragment.kt @@ -2,9 +2,14 @@ import android.bluetooth.BluetoothGatt import android.bluetooth.BluetoothGattCharacteristic +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.ServiceConnection import android.graphics.Color import android.os.Bundle import android.os.Handler +import android.os.IBinder import android.os.Message import android.os.Vibrator import android.util.Log @@ -33,6 +38,7 @@ import com.casic.birmm.inspect.extensions.toDeviceCode import com.casic.birmm.inspect.extensions.toDeviceModel import com.casic.birmm.inspect.model.NewInspectionModel +import com.casic.birmm.inspect.service.LocationService import com.casic.birmm.inspect.utils.LocaleConstant import com.casic.birmm.inspect.utils.LocationHub import com.casic.birmm.inspect.utils.SoundPoolHelper @@ -99,7 +105,8 @@ private val kTag = "HomePageFragment" private val bleManager by lazy { BleManager.getInstance() } - private val latLngs = LinkedList() + private val newModel by lazy { NewInspectionModel() }//新建巡检数据结构模型 + private val latLngList by lazy { LinkedList() } private lateinit var userName: String private lateinit var eventViewModel: EventViewModel private lateinit var inspectionViewModel: InspectionViewModel @@ -108,7 +115,6 @@ private lateinit var writeUuid: String private lateinit var notifyUuid: String private var vibrator: Vibrator? = null - private var newModel: NewInspectionModel? = null//新建巡检数据结构模型 private var connectedDevice: BleDevice? = null private var isGeneratingTask = false private var alarmCount = 0 @@ -147,49 +153,19 @@ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isCompassEnabled = true uiSettings.isZoomControlsEnabled = true + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 //显示定位小蓝点 val locationStyle = MyLocationStyle() - locationStyle.showMyLocation(true)//设置是否显示定位小蓝点 + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + //定位、移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE) aMap.myLocationStyle = locationStyle aMap.isMyLocationEnabled = true aMap.mapType = AMap.MAP_TYPE_NORMAL - LocationHub.get.getLocationByAMap(requireContext(), object : LocationHub.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - "当前信号弱,无法定位".show(requireContext()) - return - } - - val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) - - //移动到指定经纬度 - val cameraPosition = CameraPosition(latLng, 16f, 0f, 0f) - val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) - aMap.animateCamera(cameraUpdate, 1500, null) - - //newInspectionModel已完成初始化,说明已经新建巡检任务,数据可以开始保存了 - if (newModel != null) { - //设置巡检起点 - if (newModel!!.startAddress.isEmpty()) { - newModel!!.startAddress = aMapLocation.address - } - - //巡检终点每次定位都覆盖,降低调用sdk频率 - newModel!!.endAddress = aMapLocation.address - - latLngs.add(latLng) - - //绘制线 - aMap.addPolyline( - PolylineOptions().addAll(latLngs).width(10f).color(Color.RED) - ) - } - } - }) - //UserName userName = SaveKeyValues.getValue(LocaleConstant.USER_NAME, "").toString() @@ -217,8 +193,11 @@ is LoadState.Success -> { LoadingDialogHub.dismiss() + //清空newModel + newModel.clearCache() + //结束任务就清空轨迹 - latLngs.clear() + latLngList.clear() aMap.clear() //按钮状态 @@ -248,16 +227,25 @@ binding.inspectNameView.text = value binding.inspectTimeView.text = startTime - newModel = NewInspectionModel( - currentTimeMillis.id(), value, - startTime, "", currentTimeMillis.timestampToDate(), - 0.0, 0.0, "", 0.0, 0.0, "", - ArrayList(), userName - ) + newModel.id = currentTimeMillis.id() + newModel.name = value + newModel.startTime = startTime + newModel.date = currentTimeMillis.timestampToDate() + newModel.user = userName //按钮状态 binding.stopInspectButton.isEnabled = true binding.addInspectionButton.isEnabled = false + + locationService?.startLocation(object : LocationHub.ILocationListener { + override fun onAMapLocationGet(aMapLocation: AMapLocation) { + drawTaskRoute(aMapLocation) + } + + override fun onAMapLocationError() { + "当前信号弱,无法定位".show(requireContext()) + } + }) } override fun onCancelClick() { @@ -284,11 +272,11 @@ requireContext().navigatePageTo( addAll( position.toString(), - newModel!!.id, - newModel!!.name, + newModel.id, + newModel.name, connectedDeviceCode, - latLngs.last.longitude.toString(), - latLngs.last.latitude.toString() + newModel.routes.last.longitude.toString(), + newModel.routes.last.latitude.toString() ) ) } @@ -296,6 +284,33 @@ } } + private fun drawTaskRoute(aMapLocation: AMapLocation) { + Log.d(kTag, "${aMapLocation.latitude}, ${aMapLocation.longitude}") + val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) + + //移动到指定经纬度 + val cameraPosition = CameraPosition(latLng, 15f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + + //stopInspectButton isEnabled,说明已经新建巡检任务,数据可以开始保存了 + if (binding.stopInspectButton.isEnabled) { + latLngList.add(latLng) + newModel.routes = latLngList + + //设置巡检起点 + if (newModel.startAddress.isNullOrEmpty()) { + newModel.startAddress = aMapLocation.address + } + + //巡检终点每次定位都覆盖,降低调用sdk频率 + newModel.endAddress = aMapLocation.address + + //绘制线 + aMap.addPolyline(PolylineOptions().addAll(newModel.routes).width(10f).color(Color.RED)) + } + } + private fun menuButtonEvent() { //结束巡检 binding.stopInspectButton.setOnClickListener { @@ -345,8 +360,6 @@ //关闭数据传送指令 bleManager.disconnectAllDevice() - latLngs.clear() - aMap.clear()//清除原来的路线 SaveKeyValues.removeKey(LocaleConstant.DEVICE_CODE) withContext(Dispatchers.Main) { binding.currentValueView.text = "--" @@ -588,44 +601,41 @@ * * 如果保存到本地,则需要设置标识位,然后finish当前页面并提示 * */ - if (newModel == null) { - "保存失败".show(requireContext()) - return - } - - // 上传巡检位置点 - for (i in 0 until latLngs.size) { - newModel!!.routes.add(latLngs[i]) + val routes = newModel.routes + for (i in 0 until routes.size) { //上传点位 routeViewModel.uploadRoutePoint( - newModel!!.id, - latLngs[i], - System.currentTimeMillis().timestampToCompleteDate() + newModel.id, routes[i], System.currentTimeMillis().timestampToCompleteDate() ) } - val first = latLngs.first - val last = latLngs.last - newModel!!.routes.calculateDistance(object : OnDistanceSearchListener { - override fun onDistanceSearched(distance: String) { - inspectionViewModel.addInspection( - id = newModel!!.id, - deviceCode = connectedDeviceCode, - name = newModel!!.name, - startTime = newModel!!.startTime, - endTime = System.currentTimeMillis().timestampToCompleteDate(), - date = newModel!!.date, - startLng = first.longitude, - startLat = first.latitude, - newModel!!.startAddress, - endLng = last.longitude, - endLat = last.latitude, - newModel!!.endAddress, - distance, - user = userName - ) - } - }) + try { + val first = routes.first + val last = routes.last + routes.calculateDistance(object : OnDistanceSearchListener { + override fun onDistanceSearched(distance: String) { + inspectionViewModel.addInspection( + id = newModel.id, + deviceCode = connectedDeviceCode, + name = newModel.name, + startTime = newModel.startTime, + endTime = System.currentTimeMillis().timestampToCompleteDate(), + date = newModel.date, + startLng = first.longitude, + startLat = first.latitude, + startAddress = newModel.startAddress, + endLng = last.longitude, + endLat = last.latitude, + endAddress = newModel.endAddress, + distance, + user = userName + ) + } + }) + } catch (e: NoSuchElementException) { + e.printStackTrace() + "无定位数据,保存任务失败".show(requireContext()) + } } /** @@ -657,10 +667,6 @@ //如果连续超过10个报警,自动生成报警事件 alarmCount++ if (alarmCount >= 10) { - if (newModel == null) { - "没有巡检任务,无法自动记录报警".show(requireContext()) - return - } generateAlarmTask(dataModel.maxPotency) } } @@ -680,12 +686,12 @@ eventViewModel.addEventTask( id = UUID.randomUUID().toString(), - inspectionId = newModel!!.id, - name = newModel!!.name, + inspectionId = newModel.id, + name = newModel.name, createTime = System.currentTimeMillis().timestampToCompleteDate(), type = "报警事件", - lng = latLngs.last.longitude, - lat = latLngs.last.latitude, + lng = newModel.routes.last.longitude, + lat = newModel.routes.last.latitude, data = maxValue, images = "", description = "自动报警记录", @@ -713,11 +719,28 @@ } //设置标题和时间 - if (newModel == null) { - return + binding.inspectNameView.text = newModel.name + binding.inspectTimeView.text = newModel.startTime + + //绑定定位服务 + Intent(requireContext(), LocationService::class.java).also { + requireContext().bindService(it, serviceConnection, Context.BIND_AUTO_CREATE) } - binding.inspectNameView.text = newModel!!.name - binding.inspectTimeView.text = newModel!!.startTime + } + + private var locationService: LocationService? = null + + private val serviceConnection = object : ServiceConnection { + override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) { + if (iBinder is LocationService.ServiceBinder) { + locationService = iBinder.getLocationService() + Log.d(kTag, "onServiceConnected: ") + } + } + + override fun onServiceDisconnected(name: ComponentName?) { + "定位服务已断开".show(requireContext()) + } } override fun onPause() { diff --git a/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.java b/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.java new file mode 100644 index 0000000..f09810f --- /dev/null +++ b/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.java @@ -0,0 +1,141 @@ +package com.casic.birmm.inspect.model; + +import com.amap.api.maps.model.LatLng; + +import java.util.LinkedList; + +public class NewInspectionModel { + private String id; + private String name; + private String startTime; + private String endTime; + private String date; + private String startLng; + private String startLat; + private String startAddress; + private String endLng; + private String endLat; + private String endAddress; + private LinkedList routes; + private String user; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + + public String getEndTime() { + return endTime; + } + + public void setEndTime(String endTime) { + this.endTime = endTime; + } + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } + + public String getStartLng() { + return startLng; + } + + public void setStartLng(String startLng) { + this.startLng = startLng; + } + + public String getStartLat() { + return startLat; + } + + public void setStartLat(String startLat) { + this.startLat = startLat; + } + + public String getStartAddress() { + return startAddress; + } + + public void setStartAddress(String startAddress) { + this.startAddress = startAddress; + } + + public String getEndLng() { + return endLng; + } + + public void setEndLng(String endLng) { + this.endLng = endLng; + } + + public String getEndLat() { + return endLat; + } + + public void setEndLat(String endLat) { + this.endLat = endLat; + } + + public String getEndAddress() { + return endAddress; + } + + public void setEndAddress(String endAddress) { + this.endAddress = endAddress; + } + + public LinkedList getRoutes() { + return routes; + } + + public void setRoutes(LinkedList routes) { + this.routes = routes; + } + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public void clearCache() { + this.id = ""; + this.name = ""; + this.startTime = ""; + this.endTime = ""; + this.date = ""; + this.startLng = ""; + this.startLat = ""; + this.startAddress = ""; + this.endLng = ""; + this.endLat = ""; + this.endAddress = ""; + this.routes.clear(); + this.user = ""; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.kt b/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.kt deleted file mode 100644 index f08334a..0000000 --- a/app/src/main/java/com/casic/birmm/inspect/model/NewInspectionModel.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.casic.birmm.inspect.model - -import com.amap.api.maps.model.LatLng - -data class NewInspectionModel( - var id: String, - var name: String, - var startTime: String, - var endTime: String, - var date: String, - var startLng: Double, - var startLat: Double, - var startAddress: String, - var endLng: Double, - var endLat: Double, - var endAddress: String, - var routes: ArrayList, - var user: String -) \ No newline at end of file diff --git a/app/src/main/java/com/casic/birmm/inspect/single/fragment/HomePageFragment.kt b/app/src/main/java/com/casic/birmm/inspect/single/fragment/HomePageFragment.kt index 031525e..76c7846 100644 --- a/app/src/main/java/com/casic/birmm/inspect/single/fragment/HomePageFragment.kt +++ b/app/src/main/java/com/casic/birmm/inspect/single/fragment/HomePageFragment.kt @@ -2,9 +2,14 @@ import android.bluetooth.BluetoothGatt import android.bluetooth.BluetoothGattCharacteristic +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.ServiceConnection import android.graphics.Color import android.os.Bundle import android.os.Handler +import android.os.IBinder import android.os.Message import android.os.Vibrator import android.util.Log @@ -30,6 +35,7 @@ import com.casic.birmm.inspect.extensions.toDeviceCode import com.casic.birmm.inspect.extensions.toDeviceModel import com.casic.birmm.inspect.model.NewInspectionModel +import com.casic.birmm.inspect.service.LocationService import com.casic.birmm.inspect.single.view.NewEventActivity import com.casic.birmm.inspect.utils.DataBaseManager import com.casic.birmm.inspect.utils.LocaleConstant @@ -93,12 +99,12 @@ private val kTag = "HomePageFragment" private val bleManager by lazy { BleManager.getInstance() } - private val latLngs = LinkedList() + private val newModel by lazy { NewInspectionModel() }//新建巡检数据结构模型 + private val latLngList by lazy { LinkedList() } private lateinit var aMap: AMap private lateinit var writeUuid: String private lateinit var notifyUuid: String private var vibrator: Vibrator? = null - private var newModel: NewInspectionModel? = null//新建巡检数据结构模型 private var connectedDevice: BleDevice? = null private var isGeneratingTask = false private var alarmCount = 0 @@ -136,48 +142,17 @@ uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER uiSettings.isCompassEnabled = true uiSettings.isZoomControlsEnabled = true + uiSettings.isRotateGesturesEnabled = false//不许地图随手势旋转角度 uiSettings.isTiltGesturesEnabled = false//不许地图随手势倾斜角度 //显示定位小蓝点 val locationStyle = MyLocationStyle() - locationStyle.showMyLocation(true)//设置是否显示定位小蓝点 + locationStyle.radiusFillColor(Color.argb(0, 0, 0, 0)) + locationStyle.strokeColor(Color.argb(0, 0, 0, 0)) + //定位、移动到地图中心点,定位点依照设备方向旋转,并且会跟随设备移动。 + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE) aMap.myLocationStyle = locationStyle aMap.isMyLocationEnabled = true - aMap.mapType = AMap.MAP_TYPE_NORMAL - - LocationHub.get.getLocationByAMap(requireContext(), object : LocationHub.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - "当前信号弱,无法定位".show(requireContext()) - return - } - - val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) - - //移动到指定经纬度 - val cameraPosition = CameraPosition(latLng, 16f, 0f, 0f) - val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) - aMap.animateCamera(cameraUpdate, 1500, null) - - //newInspectionModel已完成初始化,说明已经新建巡检任务,数据可以开始保存了 - if (newModel != null) { - //设置巡检起点 - if (newModel!!.startAddress.isEmpty()) { - newModel!!.startAddress = aMapLocation.address - } - - //巡检终点每次定位都覆盖,降低调用sdk频率 - newModel!!.endAddress = aMapLocation.address - - latLngs.add(latLng) - - //绘制线 - aMap.addPolyline( - PolylineOptions().addAll(latLngs).width(10f).color(Color.RED) - ) - } - } - }) } override fun observeRequestState() { @@ -199,16 +174,25 @@ binding.inspectNameView.text = value binding.inspectTimeView.text = startTime - newModel = NewInspectionModel( - currentTimeMillis.id(), value, - startTime, "", currentTimeMillis.timestampToDate(), - 0.0, 0.0, "", 0.0, 0.0, "", - ArrayList(), "智巡宝" - ) + newModel.id = currentTimeMillis.id() + newModel.name = value + newModel.startTime = startTime + newModel.date = currentTimeMillis.timestampToDate() + newModel.user = "智巡宝" //按钮状态 binding.stopInspectButton.isEnabled = true binding.addInspectionButton.isEnabled = false + + locationService?.startLocation(object : LocationHub.ILocationListener { + override fun onAMapLocationGet(aMapLocation: AMapLocation) { + drawTaskRoute(aMapLocation) + } + + override fun onAMapLocationError() { + "当前信号弱,无法定位".show(requireContext()) + } + }) } override fun onCancelClick() { @@ -235,11 +219,11 @@ requireContext().navigatePageTo( addAll( position.toString(), - newModel!!.id, - newModel!!.name, + newModel.id, + newModel.name, connectedDeviceCode, - latLngs.last.longitude.toString(), - latLngs.last.latitude.toString() + newModel.routes.last.longitude.toString(), + newModel.routes.last.latitude.toString() ) ) } @@ -247,6 +231,33 @@ } } + private fun drawTaskRoute(aMapLocation: AMapLocation) { + Log.d(kTag, "${aMapLocation.latitude}, ${aMapLocation.longitude}") + val latLng = LatLng(aMapLocation.latitude, aMapLocation.longitude) + + //移动到指定经纬度 + val cameraPosition = CameraPosition(latLng, 15f, 0f, 0f) + val cameraUpdate = CameraUpdateFactory.newCameraPosition(cameraPosition) + aMap.animateCamera(cameraUpdate) + + //stopInspectButton isEnabled,说明已经新建巡检任务,数据可以开始保存了 + if (binding.stopInspectButton.isEnabled) { + latLngList.add(latLng) + newModel.routes = latLngList + + //设置巡检起点 + if (newModel.startAddress.isNullOrEmpty()) { + newModel.startAddress = aMapLocation.address + } + + //巡检终点每次定位都覆盖,降低调用sdk频率 + newModel.endAddress = aMapLocation.address + + //绘制线 + aMap.addPolyline(PolylineOptions().addAll(newModel.routes).width(10f).color(Color.RED)) + } + } + private fun menuButtonEvent() { //结束巡检 binding.stopInspectButton.setOnClickListener { @@ -296,8 +307,6 @@ //关闭数据传送指令 bleManager.disconnectAllDevice() - latLngs.clear() - aMap.clear()//清除原来的路线 SaveKeyValues.removeKey(LocaleConstant.DEVICE_CODE) withContext(Dispatchers.Main) { binding.currentValueView.text = "--" @@ -539,42 +548,51 @@ * * 如果保存到本地,则需要设置标识位,然后finish当前页面并提示 * */ - if (newModel == null) { - "保存失败".show(requireContext()) - return - } - LoadingDialogHub.show(requireActivity(), "数据保存中,请稍后...") + val routes = newModel.routes // 保存巡检位置点 lifecycleScope.launch(Dispatchers.Main) { withContext(Dispatchers.IO) { - for (i in 0 until latLngs.size) { - newModel!!.routes.add(latLngs[i]) - - DataBaseManager.get.addInspectionRoute(newModel!!.id, latLngs[i]) + for (i in 0 until routes.size) { + DataBaseManager.get.addInspectionRoute(newModel.id, routes[i]) } - DataBaseManager.get.addInspection( - inspectionId = newModel!!.id, - deviceCode = connectedDeviceCode, - inspectionName = newModel!!.name, - startTime = newModel!!.startTime, - endTime = System.currentTimeMillis().timestampToCompleteDate(), - date = newModel!!.date, - startLng = latLngs.first.longitude, - startLat = latLngs.first.latitude, - newModel!!.startAddress, - endLng = latLngs.last.longitude, - endLat = latLngs.last.latitude, - newModel!!.endAddress, - routes = newModel!!.routes - ) + try { + val first = routes.first + val last = routes.last + DataBaseManager.get.addInspection( + inspectionId = newModel.id, + deviceCode = connectedDeviceCode, + inspectionName = newModel.name, + startTime = newModel.startTime, + endTime = System.currentTimeMillis().timestampToCompleteDate(), + date = newModel.date, + startLng = first.longitude, + startLat = first.latitude, + startAddress = newModel.startAddress, + endLng = last.longitude, + endLat = last.latitude, + endAddress = newModel.endAddress, + routes = newModel.routes + ) + } catch (e: NoSuchElementException) { + e.printStackTrace() + withContext(Dispatchers.Main) { + "无定位数据,保存任务失败".show(requireContext()) + } + } } LoadingDialogHub.dismiss() + //清空newModel + newModel.clearCache() + + //停止定位 + locationService?.stopLocation() + //结束任务就清空轨迹 - latLngs.clear() + latLngList.clear() aMap.clear() //按钮状态 @@ -611,10 +629,6 @@ //如果连续超过10个报警,自动生成报警事件 alarmCount++ if (alarmCount >= 10) { - if (newModel == null) { - "没有巡检任务,无法自动记录报警".show(requireContext()) - return - } generateAlarmTask(dataModel.maxPotency) } } @@ -635,13 +649,13 @@ DataBaseManager.get.addEvent( taskId = UUID.randomUUID().toString(), - inspectionId = newModel!!.id, + inspectionId = newModel.id, deviceCode = connectedDeviceCode, - eventTitle = newModel!!.name, + eventTitle = newModel.name, createTime = System.currentTimeMillis().timestampToCompleteDate(), type = "报警事件", - lng = latLngs.last.longitude, - lat = latLngs.last.latitude, + lng = newModel.routes.last.longitude, + lat = newModel.routes.last.latitude, data = maxValue, images = "", description = "自动报警记录" @@ -671,11 +685,28 @@ } //设置标题和时间 - if (newModel == null) { - return + binding.inspectNameView.text = newModel.name + binding.inspectTimeView.text = newModel.startTime + + //绑定定位服务 + Intent(requireContext(), LocationService::class.java).also { + requireContext().bindService(it, serviceConnection, Context.BIND_AUTO_CREATE) } - binding.inspectNameView.text = newModel!!.name - binding.inspectTimeView.text = newModel!!.startTime + } + + private var locationService: LocationService? = null + + private val serviceConnection = object : ServiceConnection { + override fun onServiceConnected(name: ComponentName?, iBinder: IBinder?) { + if (iBinder is LocationService.ServiceBinder) { + locationService = iBinder.getLocationService() + Log.d(kTag, "onServiceConnected: ") + } + } + + override fun onServiceDisconnected(name: ComponentName?) { + "定位服务已断开".show(requireContext()) + } } override fun onPause() { diff --git a/app/src/main/java/com/casic/birmm/inspect/utils/DataBaseManager.kt b/app/src/main/java/com/casic/birmm/inspect/utils/DataBaseManager.kt index 3a2cac1..268f37b 100644 --- a/app/src/main/java/com/casic/birmm/inspect/utils/DataBaseManager.kt +++ b/app/src/main/java/com/casic/birmm/inspect/utils/DataBaseManager.kt @@ -12,6 +12,7 @@ import com.casic.birmm.inspect.greendao.TaskEventLocalBeanDao import com.casic.birmm.inspect.single.fragment.QueryEventFragment import com.casic.birmm.inspect.single.fragment.QueryInspectionFragment +import java.util.LinkedList class DataBaseManager private constructor() { @@ -44,7 +45,7 @@ endLng: Double, endLat: Double, endAddress: String, - routes: ArrayList + routes: LinkedList ) { val bean = InspectionLocalBean() bean.inspectionId = inspectionId diff --git a/app/src/main/java/com/casic/birmm/inspect/utils/LocationHub.kt b/app/src/main/java/com/casic/birmm/inspect/utils/LocationHub.kt index 11be914..5e12297 100644 --- a/app/src/main/java/com/casic/birmm/inspect/utils/LocationHub.kt +++ b/app/src/main/java/com/casic/birmm/inspect/utils/LocationHub.kt @@ -5,57 +5,54 @@ import com.amap.api.location.AMapLocation import com.amap.api.location.AMapLocationClient import com.amap.api.location.AMapLocationClientOption +import com.amap.api.location.AMapLocationListener class LocationHub private constructor() { private val kTag = "LocationHub" companion object { - //Kotlin委托模式双重锁单例 - val get: LocationHub by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { + val get by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { LocationHub() } } private val locationOption = AMapLocationClientOption() - private lateinit var locationClient: AMapLocationClient + private var locationClient: AMapLocationClient? = null init { //设置定位模式为高精度模式,AMapLocationMode.Battery_Saving为低功耗模式,AMapLocationMode.Device_Sensors是仅设备模式 locationOption.locationMode = AMapLocationClientOption.AMapLocationMode.Hight_Accuracy - locationOption.interval = 10 * 1000 //10s定位一次 locationOption.isNeedAddress = true //设置是否返回地址信息(默认返回地址信息) - locationOption.isLocationCacheEnable = true //可选,设置是否使用缓存定位,默认为true } /** * 高德sdk定位 */ - fun getLocationByAMap(context: Context?, listener: ILocationListener) { + fun getLocationByAMap(context: Context, listener: AMapLocationListener) { locationClient = AMapLocationClient(context) //给定位客户端对象设置定位参数 - locationClient.setLocationOption(locationOption) + locationClient?.setLocationOption(locationOption) //设置定位回调监听 - locationClient.setLocationListener { aMapLocation -> - if (aMapLocation != null) { - if (aMapLocation.errorCode == 0) { - listener.onAMapLocationGet(aMapLocation) + locationClient?.setLocationListener { + if (it != null) { + if (it.errorCode == 0) { + listener.onLocationChanged(it) } else { - Log.e( - kTag, - "ErrCode: ${aMapLocation.errorCode}, errInfo: ${aMapLocation.errorInfo}" - ) + Log.e(kTag, "errCode: ${it.errorCode}, errInfo: ${it.errorInfo}") } } } //启动定位 - locationClient.startLocation() + locationClient?.startLocation() } fun stopLocation() { - locationClient.stopLocation()//停止定位 + locationClient?.stopLocation()//停止定位 } interface ILocationListener { - fun onAMapLocationGet(aMapLocation: AMapLocation?) //高德定位数据 + fun onAMapLocationGet(aMapLocation: AMapLocation) //高德定位数据 + + fun onAMapLocationError() } } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_event_detail.xml b/app/src/main/res/layout/activity_event_detail.xml index d8dc39e..aa8cdf3 100644 --- a/app/src/main/res/layout/activity_event_detail.xml +++ b/app/src/main/res/layout/activity_event_detail.xml @@ -97,7 +97,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" - android:text="最大泄露数值" + android:text="最大泄露数值(ppm · m)" android:textColor="@color/black" android:textSize="@dimen/sp_16" /> diff --git a/app/src/main/res/layout/activity_new_event.xml b/app/src/main/res/layout/activity_new_event.xml index 3bac2d9..c910137 100644 --- a/app/src/main/res/layout/activity_new_event.xml +++ b/app/src/main/res/layout/activity_new_event.xml @@ -94,7 +94,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" - android:text="最大泄露数值" + android:text="最大泄露数值(ppm · m)" android:textColor="@color/black" android:textSize="@dimen/sp_16" /> diff --git a/app/src/main/res/layout/single_activity_event_detail.xml b/app/src/main/res/layout/single_activity_event_detail.xml index d8dc39e..aa8cdf3 100644 --- a/app/src/main/res/layout/single_activity_event_detail.xml +++ b/app/src/main/res/layout/single_activity_event_detail.xml @@ -97,7 +97,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" - android:text="最大泄露数值" + android:text="最大泄露数值(ppm · m)" android:textColor="@color/black" android:textSize="@dimen/sp_16" /> diff --git a/app/src/main/res/layout/single_activity_new_event.xml b/app/src/main/res/layout/single_activity_new_event.xml index 3bac2d9..c910137 100644 --- a/app/src/main/res/layout/single_activity_new_event.xml +++ b/app/src/main/res/layout/single_activity_new_event.xml @@ -94,7 +94,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" - android:text="最大泄露数值" + android:text="最大泄露数值(ppm · m)" android:textColor="@color/black" android:textSize="@dimen/sp_16" />