diff --git a/app/src/main/java/com/navinfo/omqs/Constant.kt b/app/src/main/java/com/navinfo/omqs/Constant.kt index f67ca0a6..7affaaab 100644 --- a/app/src/main/java/com/navinfo/omqs/Constant.kt +++ b/app/src/main/java/com/navinfo/omqs/Constant.kt @@ -59,6 +59,11 @@ class Constant { const val DEBUG = true + /** + * 是否自动定位 + */ + var AUTO_LOCATION = false + var IS_VIDEO_SPEED by kotlin.properties.Delegates.notNull() const val message_status_late = "预约,待发送" diff --git a/app/src/main/java/com/navinfo/omqs/bean/TraceVideoBean.kt b/app/src/main/java/com/navinfo/omqs/bean/TraceVideoBean.kt new file mode 100644 index 00000000..f8d0da42 --- /dev/null +++ b/app/src/main/java/com/navinfo/omqs/bean/TraceVideoBean.kt @@ -0,0 +1,8 @@ +package com.navinfo.omqs.bean + +data class TraceVideoBean( + var userid: String = "", + var playMode: String = "", + var time: String = "", + var command: String = "", +) \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/http/NetworkService.kt b/app/src/main/java/com/navinfo/omqs/http/NetworkService.kt index beca12b6..2570f031 100644 --- a/app/src/main/java/com/navinfo/omqs/http/NetworkService.kt +++ b/app/src/main/java/com/navinfo/omqs/http/NetworkService.kt @@ -6,8 +6,7 @@ import com.navinfo.omqs.bean.IndoorConnectionInfoBean import com.navinfo.omqs.bean.LoginUserBean import com.navinfo.omqs.bean.QRCodeBean import com.navinfo.omqs.bean.SysUserBean -import okhttp3.ResponseBody -import retrofit2.Response +import com.navinfo.omqs.bean.TraceVideoBean /** @@ -38,4 +37,9 @@ interface NetworkService { * 更新用户信息 */ suspend fun updateServerInfo(url: String,indoorConnectionInfoBean: IndoorConnectionInfoBean): NetResult + + /** + * 设置轨迹对应的视频 + */ + suspend fun sendServerCommand(url: String,traceVideoBean: TraceVideoBean): NetResult } \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/http/NetworkServiceImpl.kt b/app/src/main/java/com/navinfo/omqs/http/NetworkServiceImpl.kt index e2ce3a7e..059229b8 100644 --- a/app/src/main/java/com/navinfo/omqs/http/NetworkServiceImpl.kt +++ b/app/src/main/java/com/navinfo/omqs/http/NetworkServiceImpl.kt @@ -6,6 +6,7 @@ import com.navinfo.omqs.bean.IndoorConnectionInfoBean import com.navinfo.omqs.bean.LoginUserBean import com.navinfo.omqs.bean.QRCodeBean import com.navinfo.omqs.bean.SysUserBean +import com.navinfo.omqs.bean.TraceVideoBean import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import okhttp3.ResponseBody @@ -110,6 +111,33 @@ class NetworkServiceImpl @Inject constructor( map["baseurl"] = indoorConnectionInfoBean.baseurl map["platform"] = indoorConnectionInfoBean.platform + val result = netApi.retrofitUpdateServerInfo(url,map) + if (result.isSuccessful) { + if (result.code() == 200) { + NetResult.Success(result.body()) + } else { + NetResult.Failure(result.code(), result.message()) + } + } else { + NetResult.Failure(result.code(), result.message()) + } + } catch (e: Exception) { + NetResult.Error(e) + } + } + + override suspend fun sendServerCommand( + url: String, + traceVideoBean: TraceVideoBean + ): NetResult = + //在IO线程中运行 + withContext(Dispatchers.IO) { + return@withContext try { + val map: MutableMap = HashMap() + map["userid"] = traceVideoBean.userid + map["playMode"] = traceVideoBean.playMode + map["time"] = traceVideoBean.time + val result = netApi.retrofitUpdateServerInfo(url,map) if (result.isSuccessful) { if (result.code() == 200) { diff --git a/app/src/main/java/com/navinfo/omqs/ui/activity/login/LoginViewModel.kt b/app/src/main/java/com/navinfo/omqs/ui/activity/login/LoginViewModel.kt index 095664d1..086a2e19 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/activity/login/LoginViewModel.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/activity/login/LoginViewModel.kt @@ -1,6 +1,7 @@ package com.navinfo.omqs.ui.activity.login import android.content.Context +import android.content.SharedPreferences import android.util.Log import android.view.View import android.widget.Toast @@ -16,11 +17,11 @@ import com.navinfo.omqs.http.DefaultResponse import com.navinfo.omqs.http.NetResult import com.navinfo.omqs.http.NetworkService import com.navinfo.omqs.tools.FileManager +import com.navinfo.omqs.util.NetUtils import dagger.hilt.android.lifecycle.HiltViewModel import io.realm.Realm import io.realm.RealmConfiguration import kotlinx.coroutines.* -import retrofit2.Response import java.io.File import java.io.IOException import javax.inject.Inject @@ -73,7 +74,9 @@ class LoginViewModel @Inject constructor( //是不是登录成功 val loginStatus: MutableLiveData = MutableLiveData() - var jobLogin: Job? = null; + var jobLogin: Job? = null + + var sharedPreferences: SharedPreferences? = null init { loginUser.value = LoginUserBean(userCode = "haofuyue00213", passWord = "123456") @@ -98,10 +101,26 @@ class LoginViewModel @Inject constructor( if (password.isEmpty()) { Toast.makeText(context, "请输入密码", Toast.LENGTH_SHORT).show() } + sharedPreferences = + context.getSharedPreferences("USER_SHAREDPREFERENCES", Context.MODE_PRIVATE) + val userNameCache = sharedPreferences?.getString("userName", null) + val passwordCache = sharedPreferences?.getString("passWord", null) + val userCodeCache = sharedPreferences?.getString("userCode", null) + //增加缓存记录,不用每次连接网络登录 + if (userNameCache != null && passwordCache != null && userCodeCache != null) { + if (userNameCache == userName && passwordCache == password) { + viewModelScope.launch(Dispatchers.IO) { + createUserFolder(context, userCodeCache) + loginStatus.postValue(LoginStatus.LOGIN_STATUS_SUCCESS) + } + return + } + } //不指定IO,会在主线程里运行 jobLogin = viewModelScope.launch(Dispatchers.IO) { loginCheck(context, userName, password) } + } /** @@ -115,25 +134,33 @@ class LoginViewModel @Inject constructor( loginStatus.postValue(LoginStatus.LOGIN_STATUS_NET_LOADING) var userCode = "99999"; //登录访问 - when (val result = networkService.loginUser(LoginUserBean(userName,password))) { - is NetResult.Success<*> ->{ - if (result.data!=null) { + when (val result = networkService.loginUser(LoginUserBean(userName, password))) { + is NetResult.Success<*> -> { + if (result.data != null) { try { val defaultUserResponse = result.data as DefaultResponse - if(defaultUserResponse.success){ - if(defaultUserResponse.obj==null|| defaultUserResponse.obj!!.userCode==null){ + if (defaultUserResponse.success) { + if (defaultUserResponse.obj == null || defaultUserResponse.obj!!.userCode == null) { withContext(Dispatchers.Main) { - Toast.makeText(context, "服务返回用户Code信息错误", Toast.LENGTH_SHORT) + Toast.makeText( + context, + "服务返回用户Code信息错误", + Toast.LENGTH_SHORT + ) .show() } loginStatus.postValue(LoginStatus.LOGIN_STATUS_CANCEL) return - }else{ + } else { userCode = defaultUserResponse.obj?.userCode.toString() } - }else{ + } else { withContext(Dispatchers.Main) { - Toast.makeText(context, "${defaultUserResponse.msg}", Toast.LENGTH_SHORT) + Toast.makeText( + context, + "${defaultUserResponse.msg}", + Toast.LENGTH_SHORT + ) .show() } loginStatus.postValue(LoginStatus.LOGIN_STATUS_CANCEL) @@ -145,7 +172,8 @@ class LoginViewModel @Inject constructor( } } } - is NetResult.Error<*> ->{ + + is NetResult.Error<*> -> { withContext(Dispatchers.Main) { Toast.makeText(context, "${result.exception.message}", Toast.LENGTH_SHORT) .show() @@ -153,7 +181,8 @@ class LoginViewModel @Inject constructor( loginStatus.postValue(LoginStatus.LOGIN_STATUS_CANCEL) return } - is NetResult.Failure<*> ->{ + + is NetResult.Failure<*> -> { withContext(Dispatchers.Main) { Toast.makeText(context, "${result.code}:${result.msg}", Toast.LENGTH_SHORT) .show() @@ -161,12 +190,16 @@ class LoginViewModel @Inject constructor( loginStatus.postValue(LoginStatus.LOGIN_STATUS_CANCEL) return } + else -> {} } //文件夹初始化 try { loginStatus.postValue(LoginStatus.LOGIN_STATUS_FOLDER_INIT) + sharedPreferences?.edit()?.putString("userName", userName)?.commit() + sharedPreferences?.edit()?.putString("passWord", password)?.commit() + sharedPreferences?.edit()?.putString("userCode", userCode)?.commit() createUserFolder(context, userCode) } catch (e: IOException) { loginStatus.postValue(LoginStatus.LOGIN_STATUS_FOLDER_FAILURE) @@ -185,18 +218,21 @@ class LoginViewModel @Inject constructor( roomAppDatabase.getOfflineMapDao().insertOrUpdate(result.data) } } + is NetResult.Error<*> -> { withContext(Dispatchers.Main) { Toast.makeText(context, "${result.exception.message}", Toast.LENGTH_SHORT) .show() } } + is NetResult.Failure<*> -> { withContext(Dispatchers.Main) { Toast.makeText(context, "${result.code}:${result.msg}", Toast.LENGTH_SHORT) .show() } } + is NetResult.Loading -> {} else -> {} } @@ -234,7 +270,7 @@ class LoginViewModel @Inject constructor( // 拷贝配置文件到用户目录下 val omdbConfigFile = File(userFolder.absolutePath, Constant.OMDB_CONFIG); // if (!omdbConfigFile.exists()) { - ResourceUtils.copyFileFromAssets(Constant.OMDB_CONFIG, omdbConfigFile.absolutePath) + ResourceUtils.copyFileFromAssets(Constant.OMDB_CONFIG, omdbConfigFile.absolutePath) // } } diff --git a/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt b/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt index d4747786..ca816771 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainActivity.kt @@ -20,11 +20,13 @@ import androidx.navigation.findNavController import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.google.android.material.dialog.MaterialAlertDialogBuilder +import com.navinfo.collect.library.data.entity.NiLocation import com.navinfo.collect.library.map.NIMapController import com.navinfo.omqs.Constant import com.navinfo.omqs.R import com.navinfo.omqs.bean.ImportConfig import com.navinfo.omqs.bean.SignBean +import com.navinfo.omqs.bean.TraceVideoBean import com.navinfo.omqs.databinding.ActivityMainBinding import com.navinfo.omqs.http.offlinemapdownload.OfflineMapDownloadManager import com.navinfo.omqs.tools.LayerConfigUtils @@ -34,12 +36,14 @@ import com.navinfo.omqs.ui.fragment.offlinemap.OfflineMapFragment import com.navinfo.omqs.ui.fragment.qsrecordlist.QsRecordListFragment import com.navinfo.omqs.ui.fragment.signMoreInfo.SignMoreInfoFragment import com.navinfo.omqs.ui.fragment.tasklist.TaskManagerFragment +import com.navinfo.omqs.ui.other.BaseToast import com.navinfo.omqs.ui.widget.RecyclerViewSpacesItemDecoration import com.navinfo.omqs.util.FlowEventBus import com.navinfo.omqs.util.SpeakMode import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.launch import org.oscim.core.GeoPoint +import org.oscim.layers.marker.MarkerItem import org.oscim.renderer.GLViewport import org.videolan.vlc.Util import java.math.BigDecimal @@ -179,6 +183,7 @@ class MainActivity : BaseActivity() { MotionEvent.ACTION_DOWN -> { voiceOnTouchStart()//Do Something } + MotionEvent.ACTION_UP -> { voiceOnTouchStop()//Do Something } @@ -228,10 +233,18 @@ class MainActivity : BaseActivity() { ) } - //捕捉列表变化回调 + //捕捉轨迹点 viewModel.liveDataNILocationList.observe(this) { if (viewModel.isSelectTrace()) { - Toast.makeText(this, "轨迹被点击了", Toast.LENGTH_LONG).show() + //Toast.makeText(this,"轨迹被点击了",Toast.LENGTH_LONG).show() + viewModel.showMarker(this, it) + viewModel.setCurrentIndexNiLocation(it) + val traceVideoBean = TraceVideoBean( + command = "videotime?", + userid = Constant.USER_ID, + time = "${it.time}:000" + ) + viewModel.sendServerCommand(this, traceVideoBean, IndoorToolsCommand.SELECT_POINT) } } @@ -311,6 +324,55 @@ class MainActivity : BaseActivity() { } } + viewModel.liveIndoorToolsResp.observe(this) { + when (it) { + IndoorToolsResp.QR_CODE_STATUS_UPDATE_VIDEO_INFO_SUCCESS -> { + + if (viewModel.indoorToolsCommand == IndoorToolsCommand.SELECT_POINT) { + selectPointFinish(true) + } + //启动自动播放 + if (viewModel.indoorToolsCommand == IndoorToolsCommand.PLAY) { + viewModel.startTimer() + } + } + + IndoorToolsResp.QR_CODE_STATUS_UPDATE_VIDEO_INFO_FAILURE -> { + if (viewModel.indoorToolsCommand == IndoorToolsCommand.SELECT_POINT) { + selectPointFinish(false) + } + } + } + } + + //室内整理工具反向控制 + viewModel.liveIndoorToolsCommand.observe(this) { + when (it) { + IndoorToolsCommand.PLAY -> { + setPlayStatus() + } + + IndoorToolsCommand.INDEXING -> { + pausePlayTrace() + } + + IndoorToolsCommand.SELECT_POINT -> { + + } + + IndoorToolsCommand.NEXT -> { + } + + IndoorToolsCommand.REWIND -> { + } + + IndoorToolsCommand.STOP -> { + //切换为暂停状态 + pausePlayTrace() + } + } + } + lifecycleScope.launch { // 初始化地图图层控制接收器 FlowEventBus.subscribe>( @@ -330,8 +392,13 @@ class MainActivity : BaseActivity() { } } - supportFragmentManager.beginTransaction() - .add(R.id.console_fragment_layout, ConsoleFragment()).commit() + //自动连接相机 + if (viewModel.isAutoCamera()) { + viewModel.autoCamera() + } else { + supportFragmentManager.beginTransaction() + .add(R.id.console_fragment_layout, ConsoleFragment()).commit() + } } //根据输入的经纬度跳转坐标 @@ -534,10 +601,14 @@ class MainActivity : BaseActivity() { */ fun tracePointsOnclick() { viewModel.setSelectTrace(!viewModel.isSelectTrace()) + binding.mainActivityTraceSnapshotPoints.isSelected = viewModel.isSelectTrace() + if (viewModel.isSelectTrace()) { Toast.makeText(this, "请选择轨迹点!", Toast.LENGTH_LONG).show() + //调用撤销自动播放 + setViewEnable(false) + viewModel.cancelTrace() } - binding.mainActivityTraceSnapshotPoints.isSelected = viewModel.isSelectTrace() } /** @@ -548,8 +619,9 @@ class MainActivity : BaseActivity() { viewModel.setSelectTrace(false) viewModel.setMediaFlag(false) viewModel.setSelectPauseTrace(false) + binding.mainActivityMenuIndoorGroup.visibility = View.GONE binding.mainActivityTraceSnapshotPoints.isSelected = viewModel.isSelectTrace() - binding.mainActivitySnapshotMediaFlag.isSelected = viewModel.isMediaFlag() + //binding.mainActivitySnapshotMediaFlag.isSelected = viewModel.isMediaFlag() binding.mainActivitySnapshotPause.isSelected = viewModel.isSelectPauseTrace() } @@ -557,15 +629,29 @@ class MainActivity : BaseActivity() { * 点击结束轨迹操作 */ fun mediaFlagOnclick() { - viewModel.setMediaFlag(!viewModel.isMediaFlag()) - binding.mainActivitySnapshotMediaFlag.isSelected = viewModel.isMediaFlag() +/* viewModel.setMediaFlag(!viewModel.isMediaFlag()) + binding.mainActivitySnapshotMediaFlag.isSelected = viewModel.isMediaFlag()*/ } /** * 点击上一个轨迹点播放操作 */ fun rewindTraceOnclick() { - pasePlayTrace() + pausePlayTrace() + val item = + mapController.markerHandle.getNILocation(viewModel.getCurrentNiLocationIndex() - 1) + if (item != null) { + viewModel.setCurrentIndexLoction(viewModel.getCurrentNiLocationIndex() - 1) + viewModel.showMarker(this, item) + val traceVideoBean = TraceVideoBean( + command = "videotime?", + userid = Constant.USER_ID, + time = "${item.time}:000" + ) + viewModel.sendServerCommand(this, traceVideoBean, IndoorToolsCommand.REWIND) + } else { + dealNoData() + } } /** @@ -576,13 +662,74 @@ class MainActivity : BaseActivity() { binding.mainActivitySnapshotPause.isSelected = viewModel.isSelectPauseTrace() viewModel.setSelectTrace(false) binding.mainActivityTraceSnapshotPoints.isSelected = viewModel.isSelectTrace() + if (viewModel.isSelectPauseTrace()) { + playVideo() + } else { + pauseVideo() + viewModel.cancelTrace() + } + } + + @RequiresApi(Build.VERSION_CODES.N) + fun playVideo() { + if (mapController.markerHandle.getCurrentMark() == null) { + BaseToast.makeText(this, "请先选择轨迹点!", BaseToast.LENGTH_SHORT).show() + return + } + viewModel.setSelectTrace(false) + binding.mainActivityTraceSnapshotPoints.isSelected = viewModel.isSelectTrace() + val traceVideoBean = TraceVideoBean(command = "playVideo?", userid = Constant.USER_ID) + viewModel.sendServerCommand(this, traceVideoBean, IndoorToolsCommand.PLAY) + } + + /** + * 设置为播放状态 + */ + @RequiresApi(Build.VERSION_CODES.N) + fun setPlayStatus() { + //切换为播放 + viewModel.setSelectPauseTrace(true) + binding.mainActivitySnapshotPause.isSelected = viewModel.isSelectPauseTrace() + playVideo() + } + + @RequiresApi(Build.VERSION_CODES.N) + fun pauseVideo() { + val traceVideoBean = TraceVideoBean(command = "pauseVideo?", userid = Constant.USER_ID) + viewModel.sendServerCommand(this, traceVideoBean, IndoorToolsCommand.STOP) } /** * 点击下一个轨迹点 */ fun nextTraceOnclick() { - pasePlayTrace() + pausePlayTrace() + val item = + mapController.markerHandle.getNILocation(viewModel.getCurrentNiLocationIndex() + 1) + if (item != null) { + viewModel.setCurrentIndexLoction(viewModel.getCurrentNiLocationIndex() + 1) + viewModel.showMarker(this, item) + val traceVideoBean = TraceVideoBean( + command = "videotime?", + userid = Constant.USER_ID, + time = "${item.time}:000" + ) + viewModel.sendServerCommand(this, traceVideoBean, IndoorToolsCommand.NEXT) + } else { + dealNoData() + } + } + + private fun dealNoData() { + BaseToast.makeText(this, "无数据了!", Toast.LENGTH_SHORT).show() + + //无数据时自动暂停播放,并停止轨迹 + if (viewModel.isSelectPauseTrace()) { + pauseVideo() + viewModel.cancelTrace() + viewModel.setSelectPauseTrace(false) + binding.mainActivitySnapshotPause.isSelected = viewModel.isSelectPauseTrace() + } } fun pasePlayTrace() { @@ -590,6 +737,27 @@ class MainActivity : BaseActivity() { binding.mainActivityTraceSnapshotPoints.isSelected = viewModel.isSelectTrace() viewModel.setSelectPauseTrace(false) binding.mainActivitySnapshotPause.isSelected = viewModel.isSelectPauseTrace() + viewModel.cancelTrace() + } + + /** + * 选点结束 + * @param value true 选点成功 false 选点失败 + */ + private fun selectPointFinish(value: Boolean) { + if (value) { + setViewEnable(true) + viewModel.setSelectPauseTrace(false) + binding.mainActivitySnapshotPause.isSelected = viewModel.isSelectPauseTrace() + } + } + + private fun setViewEnable(value: Boolean) { + binding.mainActivitySnapshotRewind.isEnabled = value + binding.mainActivitySnapshotNext.isEnabled = value + binding.mainActivitySnapshotPause.isEnabled = value + binding.mainActivitySnapshotFinish.isEnabled = value + viewModel.cancelTrace() } @@ -686,7 +854,7 @@ class MainActivity : BaseActivity() { private fun setIndoorGroupEnable(enable: Boolean) { binding.mainActivitySnapshotFinish.isEnabled = enable binding.mainActivityTraceSnapshotPoints.isEnabled = enable - binding.mainActivitySnapshotMediaFlag.isEnabled = enable + //binding.mainActivitySnapshotMediaFlag.isEnabled = enable binding.mainActivitySnapshotRewind.isEnabled = enable binding.mainActivitySnapshotPause.isEnabled = enable binding.mainActivitySnapshotNext.isEnabled = enable diff --git a/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt b/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt index e62cc5d0..8e7e522b 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/activity/map/MainViewModel.kt @@ -15,31 +15,39 @@ import android.view.View import android.view.ViewGroup import android.widget.ImageView import android.widget.PopupWindow +import android.widget.Toast import androidx.annotation.RequiresApi import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import androidx.navigation.findNavController import com.blankj.utilcode.util.ToastUtils +import com.blankj.utilcode.util.ViewUtils.runOnUiThread import com.navinfo.collect.library.data.dao.impl.TraceDataBase import com.navinfo.collect.library.data.entity.* +import com.navinfo.collect.library.garminvirbxe.HostBean import com.navinfo.collect.library.map.NIMapController import com.navinfo.collect.library.map.OnGeoPointClickListener import com.navinfo.collect.library.map.handler.ONNoteItemClickListener import com.navinfo.collect.library.map.handler.OnNiLocationItemListener import com.navinfo.collect.library.map.handler.OnQsRecordItemClickListener -import com.navinfo.collect.library.map.handler.OnTaskLinkItemClickListener import com.navinfo.collect.library.utils.GeometryTools import com.navinfo.collect.library.utils.GeometryToolsKt import com.navinfo.omqs.Constant import com.navinfo.omqs.R import com.navinfo.omqs.bean.ImportConfig +import com.navinfo.omqs.bean.QRCodeBean import com.navinfo.omqs.bean.SignBean +import com.navinfo.omqs.bean.TraceVideoBean import com.navinfo.omqs.db.RealmOperateHelper +import com.navinfo.omqs.http.NetResult +import com.navinfo.omqs.http.NetworkService import com.navinfo.omqs.ui.dialog.CommonDialog import com.navinfo.omqs.ui.manager.TakePhotoManager +import com.navinfo.omqs.ui.other.BaseToast import com.navinfo.omqs.ui.widget.SignUtil import com.navinfo.omqs.util.DateTimeUtil +import com.navinfo.omqs.util.ShareUtil import com.navinfo.omqs.util.SoundMeter import com.navinfo.omqs.util.SpeakMode import dagger.hilt.android.lifecycle.HiltViewModel @@ -52,11 +60,14 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.oscim.core.GeoPoint import org.oscim.core.MapPosition +import org.oscim.layers.marker.MarkerItem import org.oscim.map.Map import org.videolan.libvlc.LibVlcUtil import java.io.File +import java.io.IOException import java.util.* import javax.inject.Inject +import kotlin.concurrent.fixedRateTimer /** * 创建Activity全局viewmode @@ -67,8 +78,9 @@ class MainViewModel @Inject constructor( private val mapController: NIMapController, private val traceDataBase: TraceDataBase, private val realmOperateHelper: RealmOperateHelper, + private val networkService: NetworkService, private val sharedPreferences: SharedPreferences -) : ViewModel(), SharedPreferences.OnSharedPreferenceChangeListener { +) : ViewModel(), SocketServer.OnConnectSinsListener, SharedPreferences.OnSharedPreferenceChangeListener { private val TAG = "MainViewModel" @@ -100,6 +112,8 @@ class MainViewModel @Inject constructor( */ val liveDataSignMoreInfo = MutableLiveData() + private var traceTag: String = "TRACE_TAG" + /** * 右上角菜单状态 */ @@ -131,6 +145,12 @@ class MainViewModel @Inject constructor( var currentTaskBean: TaskBean? = null + //状态 + val liveIndoorToolsResp: MutableLiveData = MutableLiveData() + + //状态 + val liveIndoorToolsCommand: MutableLiveData = MutableLiveData() + /** * 是不是线选择模式 */ @@ -155,6 +175,18 @@ class MainViewModel @Inject constructor( private var lastNiLocaion: NiLocation? = null + private var currentIndexNiLocation: Int = 0 + + private var socketServer: SocketServer? = null + + var indoorToolsCommand: IndoorToolsCommand? = null + + private var shareUtil: ShareUtil? = null + + private var timer: Timer? = null + + private var disTime :Long = 1000 + init { mapController.mMapView.vtmMap.events.bind(Map.UpdateListener { e, mapPosition -> @@ -164,6 +196,9 @@ class MainViewModel @Inject constructor( } }) + + shareUtil = ShareUtil(mapController.mMapView.context, 1) + initLocation() /** * 处理点击道路捕捉回调功能 @@ -231,6 +266,7 @@ class MainViewModel @Inject constructor( initNILocationData() } sharedPreferences.registerOnSharedPreferenceChangeListener(this) + socketServer = SocketServer(mapController, traceDataBase, sharedPreferences) } @@ -310,21 +346,10 @@ class MainViewModel @Inject constructor( * 初始化定位信息 */ private fun initLocation() { + //用于定位点存储到数据库 viewModelScope.launch(Dispatchers.Default) { //用于定位点捕捉道路 - mapController.locationLayerHandler.niLocationFlow.collectLatest { location -> - if (!isSelectRoad() && !GeometryTools.isCheckError( - location.longitude, location.latitude - ) - ) { - captureLink( - GeoPoint( - location.latitude, location.longitude - ) - ) - } - } mapController.locationLayerHandler.niLocationFlow.collect { location -> //过滤掉无效点 @@ -354,34 +379,52 @@ class MainViewModel @Inject constructor( } val id = sharedPreferences.getInt(Constant.SELECT_TASK_ID, -1) location.taskId = id.toString() + if (shareUtil?.connectstate == true) { + location.media = 1 + } + var disance = 0.0 //增加间距判断 if (lastNiLocaion != null) { - val disance = GeometryTools.getDistance( - location.latitude, - location.longitude, - lastNiLocaion!!.latitude, - lastNiLocaion!!.longitude + disance = GeometryTools.getDistance( + location.latitude, location.longitude, + lastNiLocaion!!.latitude, lastNiLocaion!!.longitude ) - //相距差距大于2.5米以上进行存储 - if (disance > 2.5) { - traceDataBase.niLocationDao.insert(location) - mapController.markerHandle.addNiLocationMarkerItem(location) - mapController.mMapView.vtmMap.updateMap(true) - lastNiLocaion = location - } - } else { + + } + //室内整理工具时不能进行轨迹存储,判断轨迹间隔要超过2.5并小于60米 + if (Constant.INDOOR_IP.isEmpty() && (disance == 0.0 || (disance > 2.5 && disance < 60))) { traceDataBase.niLocationDao.insert(location) -/* mapController.markerHandle.addNiLocationMarkerItem(location) - mapController.mMapView.vtmMap.updateMap(true)*/ + mapController.markerHandle.addNiLocationMarkerItem(location) + mapController.mMapView.vtmMap.updateMap(true) lastNiLocaion = location } } } - } + } + viewModelScope.launch(Dispatchers.Default) { + //用于定位点捕捉道路 + mapController.locationLayerHandler.niLocationFlow.collectLatest { location -> + if (!isSelectRoad() && !GeometryTools.isCheckError( + location.longitude, location.latitude + ) + ) { + captureLink( + GeoPoint( + location.latitude, location.longitude + ) + ) + } + withContext(Dispatchers.Main){ + if(Constant.AUTO_LOCATION){ + mapController.mMapView.vtmMap.animator() + .animateTo(GeoPoint( location.longitude, location.latitude)) + } + } + } + } //显示轨迹图层 mapController.layerManagerHandler.showNiLocationLayer() - } @@ -528,17 +571,8 @@ class MainViewModel @Inject constructor( Log.e("qj", LibVlcUtil.hasCompatibleCPU(context).toString()) - if (mCameraDialog == null) { - mCameraDialog = CommonDialog( - context, - context.resources.getDimension(R.dimen.head_img_width) - .toInt() * 3 + context.resources.getDimension(R.dimen.ten) - .toInt() + context.resources.getDimension(R.dimen.twenty_four).toInt(), - context.resources.getDimension(R.dimen.head_img_width).toInt() + 10, - 1 - ) - mCameraDialog!!.setCancelable(true) - } + initCameraDialog(context) + mCameraDialog!!.openCamear(mCameraDialog!!.getmShareUtil().continusTakePhotoState) mCameraDialog!!.show() mCameraDialog!!.setOnDismissListener(DialogInterface.OnDismissListener { @@ -563,6 +597,20 @@ class MainViewModel @Inject constructor( }) } + private fun initCameraDialog(context:Context){ + if (mCameraDialog == null) { + mCameraDialog = CommonDialog( + context, + context.resources.getDimension(R.dimen.head_img_width) + .toInt() * 3 + context.resources.getDimension(R.dimen.ten) + .toInt() + context.resources.getDimension(R.dimen.twenty_four).toInt(), + context.resources.getDimension(R.dimen.head_img_width).toInt() + 10, + 1 + ) + mCameraDialog!!.setCancelable(true) + } + } + fun startSoundMetter(context: Context, v: View) { //语音识别动画 @@ -727,5 +775,246 @@ class MainViewModel @Inject constructor( liveDataSignMoreInfo.value = data } + fun sendServerCommand( + context: Context, + traceVideoBean: TraceVideoBean, + indoorToolsCommand: IndoorToolsCommand + ) { + + if (TextUtils.isEmpty(Constant.INDOOR_IP)) { + Toast.makeText(context, "获取ip失败!", Toast.LENGTH_LONG).show() + return + } + + this.indoorToolsCommand = indoorToolsCommand + + viewModelScope.launch(Dispatchers.Default) { + val url = "http://${Constant.INDOOR_IP}:8080/sensor/service/${traceVideoBean.command}?" + + when (val result = networkService.sendServerCommand( + url = url, + traceVideoBean = traceVideoBean + )) { + is NetResult.Success<*> -> { + + if (result.data != null) { + try { + + val defaultUserResponse = result.data as QRCodeBean + + if (defaultUserResponse.errcode == 0) { + + withContext(Dispatchers.Main) { + Toast.makeText( + context, + "命令成功。", + Toast.LENGTH_LONG + ).show() + + liveIndoorToolsResp.postValue(IndoorToolsResp.QR_CODE_STATUS_UPDATE_VIDEO_INFO_SUCCESS) + + //启动双向控制服务 + + //启动双向控制服务 + if (socketServer != null && socketServer!!.isServerClose) { + socketServer!!.connect( + Constant.INDOOR_IP, + this@MainViewModel + ) + } + + } + } else { + withContext(Dispatchers.Main) { + Toast.makeText( + context, + "命令无效${defaultUserResponse.errmsg}", + Toast.LENGTH_SHORT + ) + .show() + } + liveIndoorToolsResp.postValue(IndoorToolsResp.QR_CODE_STATUS_UPDATE_VIDEO_INFO_FAILURE) + } + + } catch (e: IOException) { + withContext(Dispatchers.Main) { + Toast.makeText( + context, + "${e.message}", + Toast.LENGTH_SHORT + ).show() + } + } + } + } + + is NetResult.Error<*> -> { + withContext(Dispatchers.Main) { + Toast.makeText( + context, + "${result.exception.message}", + Toast.LENGTH_SHORT + ) + .show() + } + liveIndoorToolsResp.postValue(IndoorToolsResp.QR_CODE_STATUS_UPDATE_VIDEO_INFO_FAILURE) + } + + is NetResult.Failure<*> -> { + withContext(Dispatchers.Main) { + Toast.makeText( + context, + "${result.code}:${result.msg}", + Toast.LENGTH_SHORT + ) + .show() + } + liveIndoorToolsResp.postValue(IndoorToolsResp.QR_CODE_STATUS_UPDATE_VIDEO_INFO_FAILURE) + } + + else -> {} + } + + } + + } + + /** + * 显示marker + * @param trackCollection 轨迹点 + * @param type 1 提示最后一个轨迹点 非1提示第一个轨迹点 + */ + fun showMarker(context: Context, niLocation: NiLocation) { + if (mapController.markerHandle != null) { + mapController.markerHandle.removeMarker(traceTag) + if (niLocation != null) { + mapController.markerHandle.addMarker( + GeoPoint( + niLocation.latitude, + niLocation.longitude + ), traceTag, "", niLocation as java.lang.Object + ) + } + } + } + + /** + * 显示索引位置 + * @param niLocation 轨迹点 + */ + fun setCurrentIndexNiLocation(niLocation: NiLocation) { + viewModelScope.launch ( Dispatchers.IO ){ + Log.e("qj","开始$currentIndexNiLocation") + currentIndexNiLocation = mapController.markerHandle.getNILocationIndex(niLocation)!! + Log.e("qj","结束$currentIndexNiLocation") + } + } + + /** + * 设置索引位置 + * @param index 索引 + */ + fun setCurrentIndexLoction(index: Int) { + currentIndexNiLocation = index + } + + /** + * + * @return index 索引 + */ + fun getCurrentNiLocationIndex(): Int { + return currentIndexNiLocation + } + + override fun onConnect(success: Boolean) { + if (!success && socketServer != null) { + BaseToast.makeText( + mapController.mMapView.context, + "轨迹反向控制服务失败,请确认连接是否正常!", + Toast.LENGTH_SHORT + ).show() + } + } + + override fun onIndexing() { + //切换为暂停状态 + liveIndoorToolsCommand.postValue(IndoorToolsCommand.INDEXING) + } + + override fun onStop() { + liveIndoorToolsCommand.postValue(IndoorToolsCommand.STOP) + } + + override fun onPlay() { + liveIndoorToolsCommand.postValue(IndoorToolsCommand.PLAY) + } + + override fun onParseEnd() { + + } + + override fun onReceiveLocation(mNiLocation: NiLocation?) { + if (mNiLocation != null) { + setCurrentIndexNiLocation(mNiLocation) + showMarker(mapController.mMapView.context, mNiLocation) + Log.e("qj","反向控制$currentIndexNiLocation") + } else { + BaseToast.makeText( + mapController.mMapView.context, + "没有找到对应轨迹点!", + Toast.LENGTH_SHORT + ).show() + } + } + + fun isAutoCamera():Boolean{ + + return shareUtil?.connectstate == true + } + + fun autoCamera(){ + if (shareUtil?.connectstate == true) { + val hostBean1 = HostBean() + hostBean1.ipAddress = shareUtil!!.takeCameraIP + hostBean1.hardwareAddress = shareUtil!!.takeCameraMac + onClickCameraButton(mapController.mMapView.context) + mCameraDialog?.connection(hostBean1) + } + } + + fun startTimer() { + if(timer!=null){ + cancelTrace() + } + timer = fixedRateTimer("", false, disTime, disTime) { + if(currentIndexNiLocation() + + //读的线程 + private var tRecv: RecvThread? = null + + //解析线程 + private var tParse: ParseThread? = null + + //输出流 + private var outStr: OutputStream? = null + + //输入流 + private var inStr: InputStream? = null + + //状态 + var connectstatus = false + + //socket + private var client: Socket? = null + + //接收缓存 + private val sData = ByteArray(512) + + //反馈接口 + private var mListener: OnConnectSinsListener? = null + + //服务 + private val mBinder: MyBinder = MyBinder() + + //接收集合 + private val mTaskList = Collections.synchronizedList(ArrayList()) + + //连接线程 + private var connectThread: Thread? = null + + //缓存ip + private var lastIp = "" + private val mHandler: Handler = object : Handler() { + override fun handleMessage(msg: Message) { + when (msg.what) { + 0x11 -> if (mListener != null) { + if (msg.obj != null && msg.obj is NiLocation) { + mListener!!.onReceiveLocation(msg.obj as NiLocation) + } else { + mListener!!.onReceiveLocation(null) + } + } + + 0x22 -> //索引定位中 + if (mListener != null) { + mListener!!.onIndexing() + } + + 0x33 -> if (mListener != null) { + mListener!!.onConnect(true) + } + + 0x44 -> if (mListener != null) { + mListener!!.onConnect(false) + } + + 0x55 -> if (mListener != null) { + mListener!!.onPlay() + } + + 0x66 -> if (mListener != null) { + mListener!!.onStop() + } + + 0x99 -> if (mListener != null) { + mListener!!.onParseEnd() + } + + 0x999 -> if (mListener != null) { + mListener!!.onConnect(false) + disconnect() + } + } + } + } + + override fun onCreate() { + super.onCreate() + } + + override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int { + return super.onStartCommand(intent, flags, startId) + } + + override fun onDestroy() { + super.onDestroy() + } + + override fun onBind(intent: Intent): IBinder? { + return mBinder + } + + inner class MyBinder : Binder() { + // 返回Activity所关联的Service对象,这样在Activity里,就可调用Service里的一些公用方法 和公用属性 + val service: SocketServer + get() =// 返回Activity所关联的Service对象,这样在Activity里,就可调用Service里的一些公用方法 和公用属性 + this@SocketServer + } + + /** + * 启动sock连接 + * + * @param ip + * @param listener 结果回调 + */ + fun connect(ip: String, listener: OnConnectSinsListener?) { + if (connectThread != null && connectThread!!.isAlive && TextUtils.equals(lastIp, ip)) { + return + } + mListener = listener + lastIp = ip + connectThread = object : Thread() { + override fun run() { + try { + client = threadConnect.get() + if (client == null) { + client = Socket(ip, 8010) + client!!.soTimeout = 3000000 + client!!.keepAlive = true + threadConnect.set(client) + } + outStr = client!!.getOutputStream() + inStr = client!!.getInputStream() + if (tRecv != null) { + tRecv!!.cancel() + } + tRecv = RecvThread() + val thread = Thread(tRecv) + thread.start() + + //解析线程 + if (tParse != null) { + tParse!!.cancel() + } + tParse = ParseThread() + val parsethread = Thread(tParse) + parsethread.start() + + //socket启动成功 + val msg = Message() + msg.what = 0x33 + mHandler.sendMessage(msg) + if (!connectstatus) { + connectstatus = true // 更改连接状态 + } + } catch (e: Exception) { + e.printStackTrace() + //启动失败 + val msg = Message() + msg.what = 0x44 + mHandler.sendMessage(msg) + } + } + } + (connectThread as Thread).start() + } + + /** + * sock是否启动 + * + * @return true 启动 false停止 + */ + val isStart: Boolean + get() = if (connectThread != null && connectThread!!.isAlive) { + true + } else false + + /** + * 销毁连接 + */ + fun disconnect() { + try { + + //销毁线程 + if (tRecv != null) { + tRecv!!.cancel() + } + + //销毁线程 + if (tParse != null) { + tParse!!.cancel() + } + } catch (e: Exception) { + } + try { + if (outStr != null) outStr!!.close() + if (inStr != null) inStr!!.close() + if (client != null) client!!.close() + } catch (e: IOException) { + e.printStackTrace() + } + } + + /** + * 解析接收到得线程 + */ + private inner class ParseThread : Runnable { + private var runFlag = true + + //轨迹时间buffer + private val traceTimeBuffer = 1500 + private var timeIndex = 0 + fun cancel() { + runFlag = false + } + + override fun run() { + try { + while (runFlag) { + if (mTaskList.size > 0) { + timeIndex = mTaskList.size - 1 + val result = parseResult(mTaskList[timeIndex]) + var resultNiLocation: NiLocation? = null + var index: Int = -1 + if (result != null) { + when (result.type) { + 1 -> { + //先暂停播放 + val msg = Message() + msg.what = 0x22 + mHandler.sendMessage(msg) + val currentTime: Long = DateTimeUtil.getTimePointSSS( + result.data + ) + val currentTimeStr: String = DateTimeUtil.TimePointSSSToTime( + result.data + ) + + Log.e(TAG, "反向"+result.data) + + val startTime = currentTime - traceTimeBuffer + val endTme = currentTime + traceTimeBuffer + + //转换为数据库时间 + val startTimeStr: String = + DateTimeUtil.getDateSimpleTime(startTime) + + //转换为数据库时间 + val endTimeStr: String = + DateTimeUtil.getDateSimpleTime(endTme) + if (!TextUtils.isEmpty(startTimeStr) && !TextUtils.isEmpty( + endTimeStr + ) + ) { + + Log.e(TAG, "getTraceData开始") + + val list: List? = getTrackList(startTimeStr, endTimeStr, currentTimeStr) + + Log.e(TAG, "getTraceData结束") + + if (list != null && list.size > 0) { + + var disTime: Long = 0 + //只有一个点不进行判断直接返回结果 + if (list.size == 1) { + resultNiLocation = list[0] + } else { + //遍历集合取最近时间的轨迹点 + b@ for (nilocation in list) { + + if (!TextUtils.isEmpty(nilocation.time)) { + + //只获取到秒的常量 + val time: Long = + nilocation.timeStamp.toLong() + + val disTimeTemp = abs(time - currentTime) + + //如果时间相同直接返回该点 + if (disTimeTemp == 0L) { + resultNiLocation = nilocation + break@b + } else { + + //第一次不对比,取当前值 + if (disTime == 0L) { + disTime = disTimeTemp + resultNiLocation = nilocation + } else { + + //前一个差值大于当前差值则取当前相对小的值 + if (disTime - disTimeTemp > 0) { + disTime = disTimeTemp + resultNiLocation = nilocation + } + } + } + } + } + } + } + } + val msg1 = Message() + msg1.what = 0x11 + msg1.obj = resultNiLocation + if (resultNiLocation != null) { + Log.e(TAG, "反向app"+resultNiLocation.time) + } + mHandler.sendMessage(msg1) + } + + 2 -> { + val msg4 = Message() + msg4.what = 0x55 + mHandler.sendMessage(msg4) + } + + 3 -> { + val msg5 = Message() + msg5.what = 0x66 + mHandler.sendMessage(msg5) + } + } + } + + + //解析时索引与集合索引对比,如果不相同代表有新命令,需要继续解析最后一条,否则清空集合不在解析 + try { + if (timeIndex == mTaskList.size - 1) { + mTaskList.clear() + } + } catch (e: Exception) { + } + val msg2 = Message() + msg2.what = 0x99 + mHandler.sendMessage(msg2) + } + } + Thread.sleep(10) + } catch (e: Exception) { + e.printStackTrace() + val msg = Message() + msg.what = 0x99 + mHandler.sendMessage(msg) + } + } + } + + /** + * 获取轨迹数据 + * + * @param startTimeStr 起始时间 + * @param endTimeStr 结束时间 + * @param currentTimeStr 当前点时间,如果存在便直接获取一个点 + * @return list 数据集合 + */ + private fun getTrackList( + startTimeStr: String, + endTimeStr: String, + currentTimeStr: String + ): List? { + if (!TextUtils.isEmpty(startTimeStr) && !TextUtils.isEmpty(endTimeStr)) { + var startTime: Long = 0 + var endTime: Long = 0 + try { + startTime = startTimeStr.toLong() + endTime = endTimeStr.toLong() + } catch (e: java.lang.Exception) { + } + if (startTime != 0L && endTime != 0L) { + + val id = sharedPreferences.getInt(Constant.SELECT_TASK_ID, -1) + + val list: MutableList = traceDataBase.niLocationDao.findToTaskIdAll(id.toString()) + + if (list.size > 0) return list + } + } + return null + } + + /** + * 接收管道数据 + */ + private inner class RecvThread : Runnable { + private var runFlag = true + fun cancel() { + runFlag = false + } + + override fun run() { + var rlRead: Int + try { + while (runFlag) { + var line: String = "" + if (!isServerClose) { + rlRead = inStr!!.read(sData) //对方断开返回-1 + if (rlRead > 0) { + Log.e(TAG, sData.toString() + "") + line = String(sData, 0, rlRead) + mTaskList.add(line) + } else { + connectFaild("连接断开") + } + } else { + connectFaild("连接断开") + } + } + Thread.sleep(10) + } catch (e: IOException) { + connectFaild(e.toString()) + e.printStackTrace() + } + } + } + + /** + * 连接失败 + * @param e 原因 + */ + private fun connectFaild(e: String) { + val msg2 = Message() + msg2.what = 0x999 + mHandler.sendMessage(msg2) + } + + /** + * 判断是否断开连接,断开返回true,没有返回false + * @return + */ + val isServerClose: Boolean + get() { + return try { + client!!.sendUrgentData(0) //发送1个字节的紧急数据,默认情况下,服务器端没有开启紧急数据处理,不影响正常通信 + false + } catch (se: Exception) { + true + } + } + + /** + * 停止接收管道数据 + */ + fun stop() { + Log.e(TAG, "stop!") + connectstatus = false + if (tRecv != null) { + tRecv!!.cancel() + } + if (tParse != null) { + tParse!!.cancel() + } + } + + /** + * 开始接收管道数据 + */ + fun start() { + Log.e(TAG, "start!") + if (tRecv != null) { + tRecv!!.cancel() + } + tRecv = RecvThread() + val thread = Thread(tRecv) + thread.start() + + //解析线程 + if (tParse != null) { + tParse!!.cancel() + } + tParse = ParseThread() + val parsethread = Thread(tParse) + parsethread.start() + } + + fun setTraceMap() { + + } + + /** + * 轨迹反向控制回调接口 + */ + interface OnConnectSinsListener { + /** + * 连接状态 + * + * @param success true 连接成功 false 连接失败 + */ + fun onConnect(success: Boolean) + + /** + * 索引中 + */ + fun onIndexing() + + /** + * 暂停 + */ + fun onStop() + + /** + * 播放 + */ + fun onPlay() + + /** + * 结束完成 + */ + fun onParseEnd() + + /** + * 轨迹点 + * + * @param mNiLocation + */ + fun onReceiveLocation(mNiLocation: NiLocation?) + } + + /** + * 解析返回值 + * + * @return 时间信息 + */ + private fun parseResult(data: String): Result? { + var data = data + if (!TextUtils.isEmpty(data)) { + try { + data = data.replace("\n".toRegex(), "") + val json = JSONObject(data) + val type = json.optInt("type") + val mResult: Result = Result() + mResult.type = type + if (type == 1) { + mResult.data = json.optString("data", "") + } + return mResult + } catch (e: Exception) { + } + } + return null + } + + //结果类对象 + internal inner class Result : Serializable { + var type = 0 + var data: String? = null + } +} \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/ui/activity/scan/QRCodeViewModel.kt b/app/src/main/java/com/navinfo/omqs/ui/activity/scan/QRCodeViewModel.kt index 1e82d3c7..f6122749 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/activity/scan/QRCodeViewModel.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/activity/scan/QRCodeViewModel.kt @@ -33,6 +33,7 @@ enum class QrCodeStatus { * 信息更新成功 */ QR_CODE_STATUS_SERVER_INFO_SUCCESS, + } @HiltViewModel diff --git a/app/src/main/java/com/navinfo/omqs/ui/dialog/CommonDialog.java b/app/src/main/java/com/navinfo/omqs/ui/dialog/CommonDialog.java index 4cac5dc0..5168b7e0 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/dialog/CommonDialog.java +++ b/app/src/main/java/com/navinfo/omqs/ui/dialog/CommonDialog.java @@ -676,6 +676,7 @@ public class CommonDialog extends Dialog implements SurfaceHolder.Callback, IVid //当前为连接时启动已有的状态 if (connectstate) { + mOneBtConnect.setPressed(true); mOneBtConnect.setBackgroundResource(R.drawable.shape_btn_red_disconnect_bg); @@ -1525,7 +1526,7 @@ public class CommonDialog extends Dialog implements SurfaceHolder.Callback, IVid } //连接 - private void connection(HostBean hostBean) { + public void connection(HostBean hostBean) { if (hostBean != null) { SensorParams params = new SensorParams(); diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/EvaluationResultViewModel.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/EvaluationResultViewModel.kt index 509748a0..7615d1d2 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/EvaluationResultViewModel.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/EvaluationResultViewModel.kt @@ -257,6 +257,7 @@ class EvaluationResultViewModel @Inject constructor( if (classType2 != null) { classType = classType2 } + classCode = bean.renderEntity.code.toString() } //如果右侧栏没数据,给个默认值 if (liveDataQsRecordBean.value!!.classType.isEmpty()) { @@ -343,11 +344,12 @@ class EvaluationResultViewModel @Inject constructor( /** * 查询问题类型列表 */ - fun getProblemTypeList(classType: String) { + fun getProblemTypeList(scProblemTypeBean: ScProblemTypeBean) { viewModelScope.launch(Dispatchers.IO) { - getProblemList(classType) + getProblemList(scProblemTypeBean.classType) } - classTypeTemp = classType + classTypeTemp = scProblemTypeBean.classType + classCodeTemp = scProblemTypeBean.elementCode } /** @@ -464,7 +466,7 @@ class EvaluationResultViewModel @Inject constructor( mapController.markerHandle.addMarker( GeoPoint( p.latitude, p.longitude - ), TAG + ), TAG, "", null ) //获取linkid @@ -484,163 +486,163 @@ class EvaluationResultViewModel @Inject constructor( liveDataQsRecordBean.value?.attachmentBeanList = it.attachmentBeanList // 显示语音数据到界面 getChatMsgEntityList() - } + } } else { liveDataToastMessage.postValue("数据读取失败") - } - } } +} +} - /** - * 查询问题类型列表 - */ +/** + * 查询问题类型列表 + */ private suspend fun getChatMsgEntityList() { - val chatMsgEntityList: MutableList = ArrayList() - liveDataQsRecordBean.value?.attachmentBeanList?.forEach { - //1 录音 - if (it.type == 1) { - val chatMsgEntity = ChatMsgEntity() - chatMsgEntity.name = it.name - chatMsgEntity.voiceUri = Constant.USER_DATA_ATTACHEMNT_PATH - chatMsgEntityList.add(chatMsgEntity) - } - } - listDataChatMsgEntityList.postValue(chatMsgEntityList) - } - - fun addChatMsgEntity(filePath: String) { - - if (filePath.isNotEmpty()) { - var chatMsgEntityList: MutableList = ArrayList() - if (listDataChatMsgEntityList.value?.isEmpty() == false) { - chatMsgEntityList = listDataChatMsgEntityList.value!! - } + val chatMsgEntityList: MutableList = ArrayList() + liveDataQsRecordBean.value?.attachmentBeanList?.forEach { + //1 录音 + if (it.type == 1) { val chatMsgEntity = ChatMsgEntity() - chatMsgEntity.name = filePath.replace(Constant.USER_DATA_ATTACHEMNT_PATH, "").toString() + chatMsgEntity.name = it.name chatMsgEntity.voiceUri = Constant.USER_DATA_ATTACHEMNT_PATH chatMsgEntityList.add(chatMsgEntity) - - - var attachmentList: RealmList = RealmList() - - //赋值处理 - if (liveDataQsRecordBean.value?.attachmentBeanList?.isEmpty() == false) { - attachmentList = liveDataQsRecordBean.value?.attachmentBeanList!! - } - - val attachmentBean = AttachmentBean() - attachmentBean.name = chatMsgEntity.name!! - attachmentBean.type = 1 - attachmentList.add(attachmentBean) - liveDataQsRecordBean.value?.attachmentBeanList = attachmentList - - listDataChatMsgEntityList.postValue(chatMsgEntityList) } } + listDataChatMsgEntityList.postValue(chatMsgEntityList) +} - fun startSoundMetter(activity: Activity, v: View) { +fun addChatMsgEntity(filePath: String) { - if (mSpeakMode == null) { - mSpeakMode = SpeakMode(activity) + if (filePath.isNotEmpty()) { + var chatMsgEntityList: MutableList = ArrayList() + if (listDataChatMsgEntityList.value?.isEmpty() == false) { + chatMsgEntityList = listDataChatMsgEntityList.value!! + } + val chatMsgEntity = ChatMsgEntity() + chatMsgEntity.name = filePath.replace(Constant.USER_DATA_ATTACHEMNT_PATH, "").toString() + chatMsgEntity.voiceUri = Constant.USER_DATA_ATTACHEMNT_PATH + chatMsgEntityList.add(chatMsgEntity) + + + var attachmentList: RealmList = RealmList() + + //赋值处理 + if (liveDataQsRecordBean.value?.attachmentBeanList?.isEmpty() == false) { + attachmentList = liveDataQsRecordBean.value?.attachmentBeanList!! } - //语音识别动画 - if (pop == null) { - pop = PopupWindow() - pop!!.width = ViewGroup.LayoutParams.MATCH_PARENT - pop!!.height = ViewGroup.LayoutParams.WRAP_CONTENT - pop!!.setBackgroundDrawable(BitmapDrawable()) - val view = - View.inflate(activity as Context, R.layout.cv_card_voice_rcd_hint_window, null) - pop!!.contentView = view - volume = view.findViewById(R.id.volume) - } + val attachmentBean = AttachmentBean() + attachmentBean.name = chatMsgEntity.name!! + attachmentBean.type = 1 + attachmentList.add(attachmentBean) + liveDataQsRecordBean.value?.attachmentBeanList = attachmentList - pop!!.update() + listDataChatMsgEntityList.postValue(chatMsgEntityList) + } +} - Constant.IS_VIDEO_SPEED = true - //录音动画 - if (pop != null) { - pop!!.showAtLocation(v, Gravity.CENTER, 0, 0) - } - volume!!.setBackgroundResource(R.drawable.pop_voice_img) - val animation = volume!!.background as AnimationDrawable - animation.start() +fun startSoundMetter(activity: Activity, v: View) { - val name: String = DateTimeUtil.getTimeSSS().toString() + ".m4a" - if (mSoundMeter == null) { - mSoundMeter = SoundMeter() - } - mSoundMeter!!.setmListener(object : SoundMeter.OnSoundMeterListener { - @RequiresApi(Build.VERSION_CODES.Q) - override fun onSuccess(filePath: String?) { - if (!TextUtils.isEmpty(filePath) && File(filePath).exists()) { - if (File(filePath) == null || File(filePath).length() < 1600) { - ToastUtils.showLong("语音时间太短,无效!") - mSpeakMode!!.speakText("语音时间太短,无效") - stopSoundMeter() - return - } + if (mSpeakMode == null) { + mSpeakMode = SpeakMode(activity) + } + + //语音识别动画 + if (pop == null) { + pop = PopupWindow() + pop!!.width = ViewGroup.LayoutParams.MATCH_PARENT + pop!!.height = ViewGroup.LayoutParams.WRAP_CONTENT + pop!!.setBackgroundDrawable(BitmapDrawable()) + val view = + View.inflate(activity as Context, R.layout.cv_card_voice_rcd_hint_window, null) + pop!!.contentView = view + volume = view.findViewById(R.id.volume) + } + + pop!!.update() + + Constant.IS_VIDEO_SPEED = true + //录音动画 + if (pop != null) { + pop!!.showAtLocation(v, Gravity.CENTER, 0, 0) + } + volume!!.setBackgroundResource(R.drawable.pop_voice_img) + val animation = volume!!.background as AnimationDrawable + animation.start() + + val name: String = DateTimeUtil.getTimeSSS().toString() + ".m4a" + if (mSoundMeter == null) { + mSoundMeter = SoundMeter() + } + mSoundMeter!!.setmListener(object : SoundMeter.OnSoundMeterListener { + @RequiresApi(Build.VERSION_CODES.Q) + override fun onSuccess(filePath: String?) { + if (!TextUtils.isEmpty(filePath) && File(filePath).exists()) { + if (File(filePath) == null || File(filePath).length() < 1600) { + ToastUtils.showLong("语音时间太短,无效!") + mSpeakMode!!.speakText("语音时间太短,无效") + stopSoundMeter() + return } - - mSpeakMode!!.speakText("结束录音") - - addChatMsgEntity(filePath!!) } - @RequiresApi(api = Build.VERSION_CODES.Q) - override fun onfaild(message: String?) { - ToastUtils.showLong("录制失败!") - mSpeakMode!!.speakText("录制失败") - stopSoundMeter() - } - }) + mSpeakMode!!.speakText("结束录音") - mSoundMeter!!.start(Constant.USER_DATA_ATTACHEMNT_PATH + name) - ToastUtils.showLong("开始录音") - mSpeakMode!!.speakText("开始录音") - } - - //停止语音录制 - @RequiresApi(api = Build.VERSION_CODES.Q) - fun stopSoundMeter() { - //先重置标识,防止按钮抬起时触发语音结束 - Constant.IS_VIDEO_SPEED = false - if (mSoundMeter != null && mSoundMeter!!.isStartSound) { - mSoundMeter!!.stop() + addChatMsgEntity(filePath!!) } - pop?.let { - if (it.isShowing) { - it.dismiss() - } + + @RequiresApi(api = Build.VERSION_CODES.Q) + override fun onfaild(message: String?) { + ToastUtils.showLong("录制失败!") + mSpeakMode!!.speakText("录制失败") + stopSoundMeter() + } + }) + + mSoundMeter!!.start(Constant.USER_DATA_ATTACHEMNT_PATH + name) + ToastUtils.showLong("开始录音") + mSpeakMode!!.speakText("开始录音") +} + +//停止语音录制 +@RequiresApi(api = Build.VERSION_CODES.Q) +fun stopSoundMeter() { + //先重置标识,防止按钮抬起时触发语音结束 + Constant.IS_VIDEO_SPEED = false + if (mSoundMeter != null && mSoundMeter!!.isStartSound) { + mSoundMeter!!.stop() + } + pop?.let { + if (it.isShowing) { + it.dismiss() } } +} - fun savePhoto(bitmap: Bitmap) { - viewModelScope.launch(Dispatchers.IO) { - // 创建一个名为 "MyApp" 的文件夹 - val myAppDir = File(Constant.USER_DATA_ATTACHEMNT_PATH) +fun savePhoto(bitmap: Bitmap) { + viewModelScope.launch(Dispatchers.IO) { + // 创建一个名为 "MyApp" 的文件夹 + val myAppDir = File(Constant.USER_DATA_ATTACHEMNT_PATH) if (!myAppDir.exists()) myAppDir.mkdirs() // 确保文件夹已创建 - // 创建一个名为 fileName 的文件 - val file = File(myAppDir, "${UUID.randomUUID()}.png") - file.createNewFile() // 创建文件 + // 创建一个名为 fileName 的文件 + val file = File(myAppDir, "${UUID.randomUUID()}.png") + file.createNewFile() // 创建文件 - // 将 Bitmap 压缩为 JPEG 格式,并将其写入文件中 - val out = FileOutputStream(file) - bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out) - out.flush() - out.close() - var picList = mutableListOf() - if (liveDataPictureList.value == null) { - picList.add(file.absolutePath) - } else { - picList.addAll(liveDataPictureList.value!!) - picList.add(file.absolutePath) - } - liveDataPictureList.postValue(picList) + // 将 Bitmap 压缩为 JPEG 格式,并将其写入文件中 + val out = FileOutputStream(file) + bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out) + out.flush() + out.close() + var picList = mutableListOf() + if (liveDataPictureList.value == null) { + picList.add(file.absolutePath) + } else { + picList.addAll(liveDataPictureList.value!!) + picList.add(file.absolutePath) } + liveDataPictureList.postValue(picList) + } } @@ -658,5 +660,5 @@ class EvaluationResultViewModel @Inject constructor( } } } - } +} } \ No newline at end of file diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/LeftAdapter.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/LeftAdapter.kt index d5a1f5d5..261b2106 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/LeftAdapter.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/evaluationresult/LeftAdapter.kt @@ -7,7 +7,7 @@ import com.navinfo.omqs.databinding.TextItemSelectBinding import com.navinfo.omqs.ui.other.BaseRecyclerViewAdapter import com.navinfo.omqs.ui.other.BaseViewHolder -class LeftAdapter(private var itemListener: ((Int, String) -> Unit?)? = null) : +class LeftAdapter(private var itemListener: ((Int, ScProblemTypeBean) -> Unit?)? = null) : BaseRecyclerViewAdapter() { private var selectTitle = "" @@ -28,7 +28,7 @@ class LeftAdapter(private var itemListener: ((Int, String) -> Unit?)? = null) : selectTitle = title.classType notifyDataSetChanged() } - itemListener?.invoke(position, title.classType) + itemListener?.invoke(position, title) } } diff --git a/app/src/main/java/com/navinfo/omqs/ui/fragment/personalcenter/PersonalCenterFragment.kt b/app/src/main/java/com/navinfo/omqs/ui/fragment/personalcenter/PersonalCenterFragment.kt index 81eef41b..afedf335 100644 --- a/app/src/main/java/com/navinfo/omqs/ui/fragment/personalcenter/PersonalCenterFragment.kt +++ b/app/src/main/java/com/navinfo/omqs/ui/fragment/personalcenter/PersonalCenterFragment.kt @@ -17,6 +17,7 @@ import com.github.k1rakishou.fsaf.callback.FSAFActivityCallbacks import com.github.k1rakishou.fsaf.callback.FileChooserCallback import com.navinfo.collect.library.data.entity.TaskBean import com.navinfo.collect.library.map.NIMapController +import com.navinfo.omqs.Constant import com.navinfo.omqs.R import com.navinfo.omqs.databinding.FragmentPersonalCenterBinding import com.navinfo.omqs.db.ImportOMDBHelper @@ -114,12 +115,18 @@ class PersonalCenterFragment(private var indoorDataListener: ((Boolean) -> Unit? } }) } + R.id.personal_center_menu_open_auto_location -> { + Constant.AUTO_LOCATION = true + } + R.id.personal_center_menu_close_auto_location -> { + Constant.AUTO_LOCATION = false + } R.id.personal_center_menu_test -> { viewModel.readRealmData() - //108.91056000267433 34.29635901721207 + //108.90107116103331 34.29568928574205 // 定位到指定位置 niMapController.mMapView.vtmMap.animator() - .animateTo(GeoPoint( 34.29635901721207, 108.91056000267433)) + .animateTo(GeoPoint( 34.29568928574205, 108.90107116103331)) } // R.id.personal_center_menu_task_list -> { // findNavController().navigate(R.id.TaskManagerFragment) diff --git a/app/src/main/java/com/navinfo/omqs/util/ShareUtil.java b/app/src/main/java/com/navinfo/omqs/util/ShareUtil.java index b3441a8b..cb54cdb2 100644 --- a/app/src/main/java/com/navinfo/omqs/util/ShareUtil.java +++ b/app/src/main/java/com/navinfo/omqs/util/ShareUtil.java @@ -370,4 +370,5 @@ public class ShareUtil { return null; } + } diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index cdc5c529..9772781f 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -345,7 +345,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:visibility="gone" - app:constraint_referenced_ids="main_activity_snapshot_finish,main_activity_trace_snapshot_points,main_activity_snapshot_media_flag,main_activity_snapshot_rewind,main_activity_snapshot_pause,main_activity_snapshot_next" /> + app:constraint_referenced_ids="main_activity_snapshot_finish,main_activity_trace_snapshot_points,main_activity_snapshot_rewind,main_activity_snapshot_pause,main_activity_snapshot_next" /> - + android:src="@drawable/map_trace_mediaflag" />--> + + + + 0 - + + + + + + + + + + <!–不应用–> - + <!–无标线无可区分边界–> - + <!–标线–> - + <!–路牙–> - + <!–护栏–> - + <!–墙–> - + <!–道路面铺设边缘–> - + <!–虚拟三角岛–> - + <!–杆状障碍物–> - + --> @@ -1758,13 +1766,13 @@ - + - + - + @@ -1772,12 +1780,12 @@ - + - + + <!–导流区边线–> - - - - - + --> + + + + + + + diff --git a/collect-library/src/main/java/com/navinfo/collect/library/data/dao/impl/INiLocationDao.java b/collect-library/src/main/java/com/navinfo/collect/library/data/dao/impl/INiLocationDao.java index 9d362617..c4fa6f57 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/data/dao/impl/INiLocationDao.java +++ b/collect-library/src/main/java/com/navinfo/collect/library/data/dao/impl/INiLocationDao.java @@ -47,6 +47,9 @@ public interface INiLocationDao { @Query("SELECT * FROM niLocation") List findAll(); + @Query("SELECT * FROM niLocation where time>=:startTime and time<=:endTime and taskId=:taskId") + List taskIdAndTimeTofindList(String taskId,long startTime,long endTime); + @Query("SELECT * FROM niLocation where taskId =:taskId") List findToTaskIdAll(String taskId); } diff --git a/collect-library/src/main/java/com/navinfo/collect/library/data/entity/Feature.java b/collect-library/src/main/java/com/navinfo/collect/library/data/entity/Feature.java index 2707a689..0f0653c3 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/data/entity/Feature.java +++ b/collect-library/src/main/java/com/navinfo/collect/library/data/entity/Feature.java @@ -14,7 +14,7 @@ import java.util.UUID; * @Date 2022/4/14 * @Description: ${TODO}(数据基类) */ -public class Feature implements Serializable, Cloneable { +public class Feature extends Object implements Serializable, Cloneable { // //主键 // @PrimaryKey(autoGenerate = true) // public int rowId; diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LocationLayerHandler.kt b/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LocationLayerHandler.kt index 0743a60d..749b2d58 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LocationLayerHandler.kt +++ b/collect-library/src/main/java/com/navinfo/collect/library/map/handler/LocationLayerHandler.kt @@ -30,7 +30,7 @@ class LocationLayerHandler(context: AppCompatActivity, mapView: NIMapView) : // // } - val niLocationFlow = MutableSharedFlow(3) + val niLocationFlow = MutableSharedFlow(5) init { ///添加定位图层到地图,[NIMapView.LAYER_GROUPS.NAVIGATION] 是最上层layer组 @@ -67,18 +67,12 @@ class LocationLayerHandler(context: AppCompatActivity, mapView: NIMapView) : val errorCode = it.locType mCurrentLocation = it mLocationLayer.setPosition(it.latitude, it.longitude, it.radius) -// Log.e( -// "qj", -// "location==${it.longitude}==errorCode===$errorCode===${it.locTypeDescription}" -// ) + Log.e("qj", "location==${it.longitude}==errorCode===$errorCode===${it.locTypeDescription}") -// if (niLocationListener != null) { getCurrentNiLocation()?.let { it1 -> - mContext.lifecycleScope.launch(Dispatchers.Default) { + mContext.lifecycleScope.launch { niLocationFlow.emit(it1) } - -// }// niLocationListener.call(it1) } } //第一次定位成功显示当前位置 if (this.bFirst) { diff --git a/collect-library/src/main/java/com/navinfo/collect/library/map/handler/MarkHandler.kt b/collect-library/src/main/java/com/navinfo/collect/library/map/handler/MarkHandler.kt index c7aa09be..e6d262ce 100644 --- a/collect-library/src/main/java/com/navinfo/collect/library/map/handler/MarkHandler.kt +++ b/collect-library/src/main/java/com/navinfo/collect/library/map/handler/MarkHandler.kt @@ -4,7 +4,6 @@ import android.content.Context import android.graphics.BitmapFactory import android.graphics.Canvas import android.graphics.Color -import android.util.Log import androidx.appcompat.app.AppCompatActivity import androidx.core.content.res.ResourcesCompat import com.navinfo.collect.library.R @@ -197,6 +196,7 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) : if (listener is OnNiLocationItemListener) { listener.onNiLocation( tag, + index, (niLocationItemizedLayer.itemList[index] as MarkerItem).uid as NiLocation ) break @@ -211,6 +211,7 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) : } }) + addLayer(layer, NIMapView.LAYER_GROUPS.OPERATE_MARKER) layer } @@ -287,7 +288,8 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) : fun addMarker( geoPoint: GeoPoint, title: String?, - description: String? = "" + description: String? = "", + uid: java.lang.Object? = null, ) { var marker: MarkerItem? = null for (e in mDefaultMarkerLayer.itemList) { @@ -302,6 +304,7 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) : tempTitle = StringUtil.createUUID() } val marker = MarkerItem( + uid, tempTitle, description, geoPoint @@ -317,6 +320,14 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) : } } + fun getCurrentMark(): MarkerInterface? { + + if (mDefaultMarkerLayer != null) { + return mDefaultMarkerLayer.itemList[mDefaultMarkerLayer.itemList.size - 1] + } + return null + } + /** * 移除marker */ @@ -484,70 +495,61 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) : /** * 添加质检数据marker */ - public suspend fun addNiLocationMarkerItem(niLocation: NiLocation) { + fun addNiLocationMarkerItem(niLocation: NiLocation) { synchronized(this) { - Log.e("jingo", "插入定位点0 ") - - var itemizedLayer: ItemizedLayer? = null - - val direction: Double = niLocation.direction - - val geoMarkerItem: MarkerItem = ClusterMarkerItem( - niLocation, - niLocation.id, - niLocation.time, - GeoPoint(niLocation.latitude, niLocation.longitude) - ) - - //角度 - when (niLocation.media) { - 0 -> { - //角度不为0时需要预先设置marker样式并进行角度设置,否则使用图层默认的sym即可 - //角度不为0时需要预先设置marker样式并进行角度设置,否则使用图层默认的sym即可 - if (direction != 0.0) { - val symbolGpsTemp = - MarkerSymbol(niLocationBitmap, MarkerSymbol.HotspotPlace.CENTER, false) - geoMarkerItem.marker = symbolGpsTemp - geoMarkerItem.setRotation(direction.toFloat()) - } else { - val symbolGpsTemp = - MarkerSymbol(niLocationBitmap2, MarkerSymbol.HotspotPlace.CENTER, false) - geoMarkerItem.marker = symbolGpsTemp - } - Log.e( - "jingo", - "插入定位点1 ${geoMarkerItem.geoPoint.longitude} ${geoMarkerItem.geoPoint.latitude}" - ) - niLocationItemizedLayer.addItem(geoMarkerItem) - itemizedLayer = niLocationItemizedLayer - } - - 1 -> { - //角度不为0时需要预先设置marker样式并进行角度设置,否则使用图层默认的sym即可 - //角度不为0时需要预先设置marker样式并进行角度设置,否则使用图层默认的sym即可 - if (direction != 0.0) { - val symbolLidarTemp = - MarkerSymbol(niLocationBitmap1, MarkerSymbol.HotspotPlace.CENTER, false) - geoMarkerItem.marker = symbolLidarTemp - geoMarkerItem.setRotation(direction.toFloat()) - } else { - val symbolGpsTemp = - MarkerSymbol(niLocationBitmap3, MarkerSymbol.HotspotPlace.CENTER, false) - geoMarkerItem.marker = symbolGpsTemp - } - Log.e( - "jingo", - "插入定位点2 ${geoMarkerItem.geoPoint.longitude} ${geoMarkerItem.geoPoint.latitude}" - ) - niLocationItemizedLayer.addItem(geoMarkerItem) - itemizedLayer = niLocationItemizedLayer - } - - } - itemizedLayer?.update() + var geoMarkerItem = createNILocationBitmap(niLocation) + niLocationItemizedLayer.addItem(geoMarkerItem) + niLocationItemizedLayer.update() } } + private fun createNILocationBitmap(niLocation: NiLocation): MarkerItem { + + val direction: Double = niLocation.direction + + val geoMarkerItem: MarkerItem = ClusterMarkerItem( + niLocation, + niLocation.id, + niLocation.time, + GeoPoint(niLocation.latitude, niLocation.longitude) + ) + + //角度 + when (niLocation.media) { + 0 -> { + //角度不为0时需要预先设置marker样式并进行角度设置,否则使用图层默认的sym即可 + //角度不为0时需要预先设置marker样式并进行角度设置,否则使用图层默认的sym即可 + if (direction > 0.0) { + val symbolGpsTemp = + MarkerSymbol(niLocationBitmap, MarkerSymbol.HotspotPlace.CENTER, false) + geoMarkerItem.marker = symbolGpsTemp + geoMarkerItem.setRotation(direction.toFloat()) + } else { + val symbolGpsTemp = + MarkerSymbol(niLocationBitmap2, MarkerSymbol.HotspotPlace.CENTER, false) + geoMarkerItem.marker = symbolGpsTemp + } + } + + 1 -> { + //角度不为0时需要预先设置marker样式并进行角度设置,否则使用图层默认的sym即可 + //角度不为0时需要预先设置marker样式并进行角度设置,否则使用图层默认的sym即可 + if (direction > 0.0) { + val symbolLidarTemp = + MarkerSymbol(niLocationBitmap1, MarkerSymbol.HotspotPlace.CENTER, false) + geoMarkerItem.marker = symbolLidarTemp + geoMarkerItem.setRotation(direction.toFloat()) + } else { + val symbolGpsTemp = + MarkerSymbol(niLocationBitmap3, MarkerSymbol.HotspotPlace.CENTER, false) + geoMarkerItem.marker = symbolGpsTemp + } + } + } + + return geoMarkerItem + } + /** * 文字和图片拼装,文字换行 @@ -775,6 +777,38 @@ class MarkHandler(context: AppCompatActivity, mapView: NIMapView) : mMapView.updateMap(true) } + fun getNILocationItemizedLayerSize(): Int { + return niLocationItemizedLayer.itemList.size + } + + fun getNILocation(index: Int): NiLocation? { + return if (index > -1 && index < getNILocationItemizedLayerSize()) { + ((niLocationItemizedLayer.itemList[index]) as MarkerItem).uid as NiLocation + } else { + null + } + } + + fun getNILocationIndex(niLocation: NiLocation): Int? { + + var list = niLocationItemizedLayer.itemList + + if (niLocation != null && list.isNotEmpty()) { + + var index = -1 + + list.forEach { + + index += 1 + + if (((it as MarkerItem).uid as NiLocation).id.equals(niLocation.id)) { + return index + } + } + } + + return -1 + } } interface OnQsRecordItemClickListener : BaseClickListener { @@ -786,5 +820,5 @@ interface ONNoteItemClickListener : BaseClickListener { } interface OnNiLocationItemListener : BaseClickListener { - fun onNiLocation(tag: String, it: NiLocation) + fun onNiLocation(tag: String, index: Int, it: NiLocation) } \ No newline at end of file diff --git a/vtm b/vtm index 1ee201a4..dd13e533 160000 --- a/vtm +++ b/vtm @@ -1 +1 @@ -Subproject commit 1ee201a41f78f169873848209a3f3bdac36f185a +Subproject commit dd13e533c38b5738ab404c2737d7ccadeff01323