2022-01-06 高德定位记录

        package com.lcw.routel.ui.patrol
        
        import android.Manifest
        import android.annotation.TargetApi
        import android.app.Notification
        import android.app.NotificationChannel
        import android.app.NotificationManager
        import android.app.PendingIntent
        import android.content.Context.NOTIFICATION_SERVICE
        import android.content.Intent
        import android.graphics.Color
        import android.os.Build
        import android.os.Bundle
        import android.view.LayoutInflater
        import android.view.View
        import android.view.ViewGroup
        import androidx.activity.addCallback
        import androidx.lifecycle.Observer
        import androidx.lifecycle.ViewModelProvider
        import androidx.navigation.fragment.findNavController
        import com.amap.api.location.AMapLocationClient
        import com.amap.api.location.AMapLocationClientOption
        import com.amap.api.location.AMapLocationClientOption.AMapLocationMode
        import com.amap.api.location.AMapLocationClientOption.AMapLocationProtocol
        import com.amap.api.maps.AMap
        import com.amap.api.maps.AMap.CancelableCallback
        import com.amap.api.maps.CameraUpdateFactory
        import com.amap.api.maps.Projection
        import com.amap.api.maps.TextureMapView
        import com.amap.api.maps.model.*
        import com.amap.api.track.AMapTrackClient
        import com.amap.api.track.ErrorCode
        import com.amap.api.track.OnTrackLifecycleListener
        import com.amap.api.track.TrackParam
        import com.amap.api.track.query.model.*
        import com.hjq.permissions.OnPermissionCallback
        import com.hjq.permissions.XXPermissions
        import com.lcw.routel.App
        import com.lcw.routel.MainActivity
        import com.lcw.routel.R
        import com.lcw.routel.base.BaseFragment
        import com.lcw.routel.base.Constants
        import com.lcw.routel.databinding.FragmentPatrolBinding
        import com.lcw.routel.entity.LocationEntity
        import com.lcw.routel.entity.PostPatrolRecordEntity
        import com.lcw.routel.entity.PostPatrolRecordStatusEntity
        import com.lcw.routel.net.easyhttp.http.EasyLog
        import com.lcw.routel.util.*
        import com.lcw.routel.widget.dialog.RequestDialog
        import dagger.hilt.android.AndroidEntryPoint
        import javax.inject.Inject
        
        
        /**
         * desc: 一键巡查
         * <p>
         * create by lcz on 2021-12-14
         */
        @AndroidEntryPoint
        class PatrolFragment : BaseFragment(), PatrolActionHandler {
        
            @Inject
            lateinit var prefs: PreferenceStorage
        
            private lateinit var binding: FragmentPatrolBinding
            private val mViewModel: PatrolViewModel by lazy {
                ViewModelProvider(this)[PatrolViewModel::class.java]
            }
        
            private var mAMap: AMap? = null
            private var mMapView: TextureMapView? = null
        
            private var postEntity: PostPatrolRecordEntity = PostPatrolRecordEntity()
            private var postStatusEntity: PostPatrolRecordStatusEntity = PostPatrolRecordStatusEntity()
        
        
            private var singleLocationClient: AMapLocationClient? = null//单次定位
            private var continueLocationClient: AMapLocationClient? = null//连续定位
        
            private var singleLocationOption: AMapLocationClientOption? = null
            private var continueLocationOption: AMapLocationClientOption? = null
        
            private var locationMarker: Marker? = null //自定义定位小蓝点的Marker
            private var projection: Projection? = null//坐标和经纬度转换工具
            private var useMoveToLocationWithMapMode = true
            private var myCancelCallback: MyCancelCallback = MyCancelCallback()
        
            private var locationAddress = ""
            private lateinit var locationLatLng: LatLng
            private var latitude = 0.0
            private var longitude = 0.0
        
            private var isServiceRunning = false//viewModel 暂存
        
        
            private var aMapTrackClient: AMapTrackClient? = null
        
            private var terminalId: Long = 0
            private var trackId: Long = 0
        
        
            private val needPermissions = arrayOf(
                Manifest.permission.ACCESS_COARSE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION
            )
        
            override fun initContentView(inflater: LayoutInflater, container: ViewGroup?): View {
                binding = FragmentPatrolBinding.inflate(inflater, container, false).apply {
                    lifecycleOwner = viewLifecycleOwner
                    viewModel = mViewModel
                }
                binding.actionHandler = this
                mMapView = binding.mMapView
                return binding.root
            }
        
            override fun process(savedInstanceState: Bundle?) {
                // 不要使用Activity作为Context传入
                aMapTrackClient = AMapTrackClient(App.appContext)
                aMapTrackClient?.setInterval(4, 8)
                mMapView?.onCreate(savedInstanceState)
                if (mAMap == null) {
                    mAMap = mMapView?.map
                    setUpMap()
                }
                initLocation()
                XXPermissions.with(this).permission(needPermissions)
                    .request(object : OnPermissionCallback {
                        override fun onGranted(permissions: MutableList<String>?, all: Boolean) {
                            if (all) {
        //                        startSingleLocation()
                                // 启用地图内置定位
                                mAMap?.moveCamera(CameraUpdateFactory.zoomTo(17f))
                                mAMap?.isMyLocationEnabled = true
                                mAMap?.myLocationStyle = MyLocationStyle().interval(3000)
                                    .myLocationIcon(BitmapDescriptorFactory.fromResource(R.mipmap.location))
                                    .myLocationType(MyLocationStyle.LOCATION_TYPE_FOLLOW)
                                    .strokeColor(Color.argb(0, 0, 0, 0))
                                    .radiusFillColor(Color.argb(0, 0, 0, 0))
                                mAMap?.addOnMyLocationChangeListener {
                                    val location = GsonUtil.json2Bean(
                                        GsonUtil.bean2Json(it),
                                        LocationEntity::class.java
                                    )
                                    latitude = location.latitude!! //纬    度
                                    longitude = location.longitude!!//经    度
                                    locationAddress = location.address.toString()
                                    locationLatLng = LatLng(latitude, longitude)
                                    EasyLog.print("经度---$longitude  纬度---$latitude  地址---$locationAddress")
        
        //                            if (location.errorCode == 0) {
        //                                EasyLog.print("定位成功")
        //                                latitude = location.latitude//纬    度
        //                                longitude = location.longitude//经    度
        //                                locationAddress = location.address
        //                                EasyLog.print("经    度---" + longitude + " 纬    度---" + latitude + " 地    址---" + location.address)
        //                                locationLatLng = LatLng(latitude, longitude)
        //                                if (locationMarker == null) {
        //                                    locationMarker = mAMap?.addMarker(
        //                                        MarkerOptions()
        //                                            .position(locationLatLng)
        //                                            .icon(BitmapDescriptorFactory.fromResource(R.mipmap.location))
        //                                            .anchor(0.5f, 0.5f)
        //                                    )
        //                                    mAMap?.moveCamera(
        //                                        CameraUpdateFactory.newLatLngZoom(
        //                                            locationLatLng,
        //                                            17f
        //                                        )
        //                                    )
        //                                } else {
        //                                    if (useMoveToLocationWithMapMode) {
        //                                        startMoveLocationAndMap(locationLatLng)
        //                                    } else {
        //                                        startChangeLocation(locationLatLng)
        //                                    }
        //                                }
        //                            } else {
        //                                EasyLog.print("定位失败---" + location.errorCode + " 错误信息---" + location.errorInfo + " 错误描述---" + location.locationDetail)
        //                            }
                                }
                            } else {
                                "部分权限获取失败".showToast()
                            }
                        }
        
                        override fun onDenied(permissions: MutableList<String>?, never: Boolean) {
                            if (never) {
                                "被永久拒绝授权,请手动授予权限".showToast()
                            } else {
                                "权限获取失败".showToast()
                            }
                        }
        
                    })
        
        
                mViewModel.isServiceRunning.observe(this, Observer {
                    EasyLog.print("isServiceRunning--------------$it")
                    isServiceRunning = it
                    if (it) {
                        mViewModel.startRefreshTimer()
                        binding.mTrackAction.text = "停止巡查"
                        binding.mTrackAction.setBackgroundResource(R.drawable.stop_track_selector)
                        // 开启巡查持续时间统计
                        onActionLocation()
                    } else {
                        mViewModel.stopRefreshTimer()
                        binding.mTrackAction.text = "开始巡查"
                        binding.mTrackAction.setBackgroundResource(R.drawable.track_selector)
                        if (isPressBack) {
                            findNavController().popBackStack()
                        }
                    }
                })
        
                mViewModel.terminalId.observe(this, EventObserver {
                    EasyLog.print("savedStateHandle terminal_id--------------$it")
                    terminalId = it
                })
        
                mViewModel.trackId.observe(this, EventObserver {
                    EasyLog.print("savedStateHandle trackId--------------$it")
                    trackId = it
                })
            }
        
            private fun setUpMap() {
                mAMap?.uiSettings?.isZoomControlsEnabled = false//缩放按钮
            }
        
            /*开启单次定位*/
            private fun startSingleLocation() {
                try {
                    // 启动定位
                    singleLocationClient!!.startLocation()
                } catch (e: java.lang.Exception) {
                    e.printStackTrace()
                }
            }
        
            /*开启连续定位*/
            private fun startContinueLocation() {
                try {
                    // 启动定位
                    continueLocationClient!!.startLocation()
                } catch (e: java.lang.Exception) {
                    e.printStackTrace()
                }
            }
        
            /*关闭连续定位*/
            private fun stopContinueLocation() {
                try {
                    // 启动定位
                    continueLocationClient!!.stopLocation()
                } catch (e: java.lang.Exception) {
                    e.printStackTrace()
                }
            }
        
        
            private fun initLocation() {
                try {
                    //单次定位
                    singleLocationClient = AMapLocationClient(App.appContext)
                    singleLocationOption = getDefaultOption(true)
                    singleLocationClient?.setLocationOption(singleLocationOption)
                    singleLocationClient?.setLocationListener { location ->
                        if (location.errorCode == 0) {
                            EasyLog.print("定位成功")
                            latitude = location.latitude//纬    度
                            longitude = location.longitude//经    度
                            locationAddress = location.address
                            EasyLog.print("经    度---" + longitude + " 纬    度---" + latitude + " 地    址---" + location.address)
                            locationLatLng = LatLng(latitude, longitude)
                            if (locationMarker == null) {
                                locationMarker = mAMap?.addMarker(
                                    MarkerOptions()
                                        .position(locationLatLng)
                                        .icon(BitmapDescriptorFactory.fromResource(R.mipmap.location))
                                        .anchor(0.5f, 0.5f)
                                )
                                mAMap?.moveCamera(CameraUpdateFactory.newLatLngZoom(locationLatLng, 17f))
                            } else {
                                if (useMoveToLocationWithMapMode) {
                                    startMoveLocationAndMap(locationLatLng)
                                } else {
                                    startChangeLocation(locationLatLng)
                                }
                            }
                        } else {
                            EasyLog.print("定位失败---" + location.errorCode + " 错误信息---" + location.errorInfo + " 错误描述---" + location.locationDetail)
                        }
                    }
        
                    //连续定位
                    continueLocationClient = AMapLocationClient(App.appContext)
                    continueLocationOption = getDefaultOption(false)
                    continueLocationClient?.setLocationOption(continueLocationOption)
                    continueLocationClient?.setLocationListener { location ->
                        if (location.errorCode == 0) {
                            EasyLog.print("定位成功")
                            latitude = location.latitude//纬    度
                            longitude = location.longitude//经    度
                            locationAddress = location.address
                            EasyLog.print("经    度---" + longitude + " 纬    度---" + latitude + " 地    址---" + location.address)
                            locationLatLng = LatLng(latitude, longitude)
                            if (locationMarker == null) {
                                locationMarker = mAMap?.addMarker(
                                    MarkerOptions()
                                        .position(locationLatLng)
                                        .icon(BitmapDescriptorFactory.fromResource(R.mipmap.location))
                                        .anchor(0.5f, 0.5f)
                                )
                                mAMap?.moveCamera(CameraUpdateFactory.newLatLngZoom(locationLatLng, 17f))
                            } else {
                                if (useMoveToLocationWithMapMode) {
                                    startMoveLocationAndMap(locationLatLng)
                                } else {
                                    startChangeLocation(locationLatLng)
                                }
                            }
                        } else {
                            EasyLog.print("定位失败---" + location.errorCode + " 错误信息---" + location.errorInfo + " 错误描述---" + location.locationDetail)
                        }
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                }
        
            }
        
        
            /**
             * 默认的定位参数 单次定位 连续定位
             */
            private fun getDefaultOption(isOnceLocation: Boolean): AMapLocationClientOption? {
                val mOption = AMapLocationClientOption()
                mOption.locationMode =
                    AMapLocationMode.Hight_Accuracy //可选,设置定位模式,可选的模式有高精度、仅设备、仅网络。默认为高精度模式
                mOption.isGpsFirst = false //可选,设置是否gps优先,只在高精度模式下有效。默认关闭
                mOption.httpTimeOut = 30000 //可选,设置网络请求超时时间。默认为30秒。在仅设备模式下无效
                mOption.interval = 2000 //可选,设置定位间隔。默认为2秒
                mOption.isNeedAddress = true //可选,设置是否返回逆地理地址信息。默认是true
                mOption.isOnceLocation = isOnceLocation //可选,设置是否单次定位。默认是false
                mOption.isOnceLocationLatest =
                    false //可选,设置是否等待wifi刷新,默认为false.如果设置为true,会自动变为单次定位,持续定位时不要使用
                AMapLocationClientOption.setLocationProtocol(AMapLocationProtocol.HTTP) //可选, 设置网络请求的协议。可选HTTP或者HTTPS。默认为HTTP
                mOption.isSensorEnable = false //可选,设置是否使用传感器。默认是false
                mOption.isWifiScan =
                    true //可选,设置是否开启wifi扫描。默认为true,如果设置为false会同时停止主动刷新,停止以后完全依赖于系统刷新,定位位置可能存在误差
                mOption.isLocationCacheEnable = true //可选,设置是否使用缓存定位,默认为true
                mOption.geoLanguage =
                    AMapLocationClientOption.GeoLanguage.DEFAULT //可选,设置逆地理信息的语言,默认值为默认语言(根据所在地区选择语言)
                return mOption
            }
        
        
            /**
             * 修改自定义定位小蓝点的位置
             * @param latLng
             */
            private fun startChangeLocation(latLng: LatLng) {
                if (locationMarker != null) {
                    val curLatlng = locationMarker!!.position
                    if (curLatlng == null || curLatlng != latLng) {
                        locationMarker!!.position = latLng
                    }
                }
            }
        
            /**
             * 监控地图动画移动情况,如果结束或者被打断,都需要执行响应的操作
             */
            inner class MyCancelCallback : CancelableCallback {
                private var targetLatlng: LatLng? = null
                fun setTargetLatlng(latlng: LatLng?) {
                    targetLatlng = latlng
                }
        
                override fun onFinish() {
                    if (locationMarker != null && targetLatlng != null) {
                        locationMarker!!.position = targetLatlng
                    }
                }
        
                override fun onCancel() {
                    if (locationMarker != null && targetLatlng != null) {
                        locationMarker!!.position = targetLatlng
                    }
                }
            }
        
            /**
             * 同时修改自定义定位小蓝点和地图的位置
             * @param latLng
             */
            private fun startMoveLocationAndMap(latLng: LatLng) {
                //将小蓝点提取到屏幕上
                if (projection == null) {
                    projection = mAMap?.projection
                }
                if (locationMarker != null && projection != null) {
                    val markerLocation = locationMarker!!.position
                    val screenPosition: android.graphics.Point? =
                        mAMap?.projection?.toScreenLocation(markerLocation)
                    locationMarker!!.setPositionByPixels(screenPosition!!.x, screenPosition!!.y)
                }
        
                //移动地图,移动结束后,将小蓝点放到放到地图上
                myCancelCallback.setTargetLatlng(latLng)
                //动画移动的时间,最好不要比定位间隔长,如果定位间隔2000ms 动画移动时间最好小于2000ms,可以使用1000ms
                //如果超过了,需要在myCancelCallback中进行处理被打断的情况
        //        mAMap?.animateCamera(CameraUpdateFactory.changeLatLng(latLng), 1000, myCancelCallback)
                mAMap?.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 17f), 1000, myCancelCallback)
            }
        
        
            override fun onResume() {
                super.onResume()
                mMapView?.onResume()
                EasyLog.print("onResume---------------")
                if (isServiceRunning) {//页面被销毁,重新 bindService
                    startTrack()
                }
            }
        
            override fun onPause() {
                super.onPause()
                EasyLog.print("onPause---------------")
                mMapView?.onPause()
            }
        
            override fun onStop() {
                super.onStop()
                EasyLog.print("onStop---------------")
            }
        
            override fun onSaveInstanceState(outState: Bundle) {
                super.onSaveInstanceState(outState)
                mMapView?.onSaveInstanceState(outState)
            }
        
            override fun onDestroyView() {
                super.onDestroyView()
                EasyLog.print("onDestroyView---------------")
                mMapView?.onDestroy()
                if (isServiceRunning) {
                    aMapTrackClient?.stopTrack(
                        TrackParam(Constants.SERVICE_ID, terminalId),
                        SimpleOnTrackLifecycleListener()
                    )
                }
                destroyLocation()
                //fix Navigation 销毁 Fragment 导致 mMapView?.onSaveInstanceState(outState) 失败
                mAMap?.clear()
                mAMap = null
                locationMarker = null
            }
        
            private fun destroyLocation() {
                if (null != singleLocationClient) {
                    /**
                     * 如果AMapLocationClient是在当前Activity实例化的,
                     * 在Activity的onDestroy中一定要执行AMapLocationClient的onDestroy
                     */
                    singleLocationClient!!.onDestroy()
                    singleLocationClient = null
                    singleLocationOption = null
                }
        
                if (null != continueLocationClient) {
                    /**
                     * 如果AMapLocationClient是在当前Activity实例化的,
                     * 在Activity的onDestroy中一定要执行AMapLocationClient的onDestroy
                     */
                    continueLocationClient!!.onDestroy()
                    continueLocationClient = null
                    continueLocationOption = null
                }
            }
        
            override fun onActionStartPatrol() {
                if (isServiceRunning) {
                    stopTrackAction("确定要结束巡查吗?")
                } else {
                    startTrack()
                }
            }
        
            /*开始巡查 上报巡查记录到高德*/
            private fun addPatrolServiceRecord() {
                postEntity.terminal_id = terminalId.toString()
                postEntity.track_id = trackId.toString()
                postEntity.detail_address = locationAddress
                mViewModel.submitMapPatrolRecord(postEntity)
            }
        
            /*结束巡查 更新巡查记录状态*/
            private fun updatePatrolServiceStatus() {
        //        stopContinueLocation()
                postStatusEntity.track_id = trackId.toString()
                postStatusEntity.detail_address = locationAddress
                mViewModel.updateMapPatrolRecordStatus(postStatusEntity)
            }
        
            private fun stopTrack() {
                aMapTrackClient!!.stopTrack(
                    TrackParam(Constants.SERVICE_ID, terminalId),
                    onTrackListener
                )
            }
        
            private fun startTrack() {
        //        startContinueLocation()
                // 先根据Terminal名称查询Terminal ID,如果Terminal还不存在,就尝试创建,拿到Terminal ID后,
                // 用Terminal ID开启轨迹服务
                aMapTrackClient?.queryTerminal(
                    QueryTerminalRequest(
                        Constants.SERVICE_ID,
                        prefs.userId
                    ), object : SimpleOnTrackListener() {
                        override fun onQueryTerminalCallback(queryTerminalResponse: QueryTerminalResponse) {
                            if (queryTerminalResponse.isSuccess) {
                                if (queryTerminalResponse.isTerminalExist) {
                                    // 当前终端已经创建过,直接使用查询到的terminal id
                                    terminalId = queryTerminalResponse.tid
                                    mViewModel.saveTerminalId(terminalId)
                                    aMapTrackClient!!.addTrack(
                                        AddTrackRequest(
                                            Constants.SERVICE_ID,
                                            terminalId
                                        ), object : SimpleOnTrackListener() {
                                            override fun onAddTrackCallback(addTrackResponse: AddTrackResponse) {
                                                if (addTrackResponse.isSuccess) {
                                                    // trackId需要在启动服务后设置才能生效,因此这里不设置,而是在startGather之前设置了track id
                                                    if (trackId == 0L) {
                                                        trackId = addTrackResponse.trid
                                                        mViewModel.saveTrackId(trackId)
                                                    }
                                                    val trackParam =
                                                        TrackParam(Constants.SERVICE_ID, terminalId)
                                                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                                                        trackParam.notification = createNotification()
                                                    }
                                                    //已经启动过的终端,重新bind
                                                    aMapTrackClient!!.startTrack(
                                                        trackParam,
                                                        onTrackListener
                                                    )
                                                } else {
                                                    "网络请求失败".showToast()
                                                }
                                            }
                                        })
                                } else {
                                    // 当前终端是新终端,还未创建过,创建该终端并使用新生成的terminal id
                                    aMapTrackClient!!.addTerminal(
                                        AddTerminalRequest(
                                            prefs.userId,
                                            Constants.SERVICE_ID
                                        ), object : SimpleOnTrackListener() {
                                            override fun onCreateTerminalCallback(addTerminalResponse: AddTerminalResponse) {
                                                if (addTerminalResponse.isSuccess) {
                                                    terminalId = addTerminalResponse.tid
                                                    mViewModel.saveTerminalId(terminalId)
                                                    val trackParam =
                                                        TrackParam(Constants.SERVICE_ID, terminalId)
                                                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                                                        trackParam.notification = createNotification()
                                                    }
                                                    aMapTrackClient!!.startTrack(
                                                        trackParam,
                                                        onTrackListener
                                                    )
                                                } else {
                                                    "网络请求失败".showToast()
                                                }
                                            }
                                        })
                                }
                            } else {
                                "网络请求失败".showToast()
                            }
                        }
                    })
            }
        
            private val onTrackListener: OnTrackLifecycleListener =
                object : SimpleOnTrackLifecycleListener() {
                    override fun onBindServiceCallback(status: Int, msg: String) {
                        EasyLog.print("onBindServiceCallback, status: $status, msg: $msg")
                    }
        
                    override fun onStartTrackCallback(status: Int, msg: String) {
                        when (status) {
                            ErrorCode.TrackListen.START_TRACK_SUCEE, ErrorCode.TrackListen.START_TRACK_SUCEE_NO_NETWORK -> {
                                // 成功启动
                                "巡查服务启动成功".showToast()
                                if (!isServiceRunning) {
                                    addPatrolServiceRecord()
                                }
                                mViewModel.isRunningServiceStatusChanged(true)
                                startGather()
                            }
                            ErrorCode.TrackListen.START_TRACK_ALREADY_STARTED -> {
                                // 已经启动
                                "巡查服务已经启动".showToast()
                                startGather()
                            }
                            else -> {
                                EasyLog.print("error onStartTrackCallback, status: $status, msg: $msg")
                                "error onStartTrackCallback, status: $status, msg: $msg".showToast()
                            }
                        }
                    }
        
                    override fun onStopTrackCallback(status: Int, msg: String) {
                        if (status == ErrorCode.TrackListen.STOP_TRACK_SUCCE) {
                            // 成功停止
                            "巡查服务已结束".showToast()
                            mViewModel.isRunningServiceStatusChanged(false)
                            updatePatrolServiceStatus()
                        } else {
                            EasyLog.print("error onStopTrackCallback, status: $status, msg: $msg")
                            "error onStopTrackCallback, status: $status, msg: $msg".showToast()
                        }
                    }
        
                    override fun onStartGatherCallback(status: Int, msg: String) {
                        when (status) {
                            ErrorCode.TrackListen.START_GATHER_SUCEE -> {
                                "定位采集开启成功".showToast()
                            }
                            ErrorCode.TrackListen.START_GATHER_ALREADY_STARTED -> {
                                "定位采集已经开启".showToast()
                            }
                            else -> {
                                EasyLog.print("error onStartGatherCallback, status: $status, msg: $msg")
                                "error onStartGatherCallback, status: $status, msg: $msg".showToast()
                            }
                        }
                    }
        
                    override fun onStopGatherCallback(status: Int, msg: String) {
                        if (status == ErrorCode.TrackListen.STOP_GATHER_SUCCE) {
                            "定位采集停止成功".showToast()
                            stopTrack()
                        } else {
                            EasyLog.print("error onStopGatherCallback, status: $status, msg: $msg")
                            "error onStopGatherCallback, status: $status, msg: $msg".showToast()
                        }
                    }
                }
        
            private fun startGather() {
                aMapTrackClient?.startGather(onTrackListener)
            }
        
            private fun stopGather() {
                aMapTrackClient?.trackId = trackId
                aMapTrackClient?.stopGather(onTrackListener)
            }
        
            /**
             * 在8.0以上手机,如果app切到后台,系统会限制定位相关接口调用频率
             * 可以在启动轨迹上报服务时提供一个通知,这样Service启动时会使用该通知成为前台Service,可以避免此限制
             */
            @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
            private fun createNotification(): Notification? {
                val builder: Notification.Builder = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    val nm =
                        mContext.getSystemService(NOTIFICATION_SERVICE) as NotificationManager?
                    val channel = NotificationChannel(
                        "CHANNEL_ID_SERVICE_RUNNING",
                        "app service",
                        NotificationManager.IMPORTANCE_LOW
                    )
                    nm!!.createNotificationChannel(channel)
                    Notification.Builder(App.appContext, "CHANNEL_ID_SERVICE_RUNNING")
                } else {
                    Notification.Builder(App.appContext)
                }
                val nfIntent = Intent(context, MainActivity::class.java)
                nfIntent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP
                builder.setContentIntent(
                    PendingIntent.getActivity(
                        context,
                        0,
                        nfIntent,
                        0
                    )
                )
                    .setSmallIcon(R.mipmap.ic_launcher)
                    .setContentTitle("道路云养护运行中")
                    .setContentText("道路云养护运行中")
                return builder.build()
            }
        
            private fun stopTrackAction(tip: String) {
                EasyLog.print("stopTrackAction-------------$terminalId")
                // 弹框提示是否结束
                RequestDialog(mContext, tip) {
                    stopGather()
                }
            }
        
            override fun onActionEditReport() {
        //        if (!isServiceRunning) {
        //            "请先开始巡查".showToast()
        //            return
        //        }
                findNavController().safeNavigate(
                    PatrolFragmentDirections.actionPatrolFragmentToMapReportFragment(
                        locationAddress, latitude.toFloat(), longitude.toFloat(), trackId.toString()
                    )
                )
            }
        
            private var isPressBack = false
            override fun onActionBack() {
                isPressBack = true
                if (isServiceRunning) {
                    stopTrackAction("确定要结束巡查吗?")
                } else {
                    findNavController().popBackStack()
                }
            }
        
            override fun onActionLocation() {
        
            }
        
            override fun initViewListener() {
                activity?.onBackPressedDispatcher?.addCallback(this) {
                    isPressBack = true
                    if (isServiceRunning) {
                        stopTrackAction("确定要结束巡查吗?")
                    } else {
                        findNavController().popBackStack()
                    }
                }
            }
        
        
            companion object {
                fun newInstance() = PatrolFragment()
            }
        
        
        }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容