diff --git a/app/build.gradle b/app/build.gradle
index 3fda936..eebcae9 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -30,7 +30,7 @@ android {
targetSdkVersion 35
versionCode 2101
// versionName "2.1.1"
- versionName "2.1.1-Beta2"
+ versionName "2.1.1-Beta4"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 8887a14..0aa0666 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -391,6 +391,10 @@
android:name=".ui.activity.map.LiveActivityV2"
android:exported="false"
android:screenOrientation="portrait" />
+
?,
var wifiZones: MutableList?,
var startTime: String,
- var endTime: String
+ var endTime: String,
+ var canShowBattery: Boolean,
+ var isCloseBattery: Boolean,
+ var isCloseMsg: Boolean
) : Parcelable {
constructor() : this(
"",
@@ -65,6 +68,9 @@ data class MapDeviceBean(
null,
null,
"",
- ""
+ "",
+ false,
+ false,
+ false
)
}
diff --git a/app/src/main/java/com/abbidot/tracker/ui/activity/HomeV2Activity.kt b/app/src/main/java/com/abbidot/tracker/ui/activity/HomeV2Activity.kt
index 23913fa..f50bd48 100644
--- a/app/src/main/java/com/abbidot/tracker/ui/activity/HomeV2Activity.kt
+++ b/app/src/main/java/com/abbidot/tracker/ui/activity/HomeV2Activity.kt
@@ -102,6 +102,7 @@ class HomeV2Activity : BaseActivity(ActivityHomeV2Binding
private val mBleReportManage: BleReportManage by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
mSocketUtilManage = SocketUtilManage()
mSocketUtilManage?.initEasySocket(mContext)
+ LogUtil.e("创建Socket连接")
BleReportManage(mSocketSendMessageViewModel, mSocketUtilManage!!)
}
@@ -222,8 +223,13 @@ class HomeV2Activity : BaseActivity(ActivityHomeV2Binding
XEventBus.observe(this, EventName.ConnectDeviceState) { ble: BleTrackDeviceBean ->
getPet(false)?.apply {
//蓝牙连接断开上传日志
- if (ble.mac == macID && ble.conState == ConState.DISCONNECTED) {
- mLogBleReportViewModel.uploadLog(mContext, macID)
+ if (ble.mac == macID) {
+ if (ble.conState == ConState.CONNECTED) {
+ //蓝牙连接就去连接socket
+ mBleReportManage.dealBleReportData(macID, null)
+ } else {
+ mLogBleReportViewModel.uploadLog(mContext, macID)
+ }
}
}
}
@@ -338,7 +344,6 @@ class HomeV2Activity : BaseActivity(ActivityHomeV2Binding
getPet(false)?.apply {
mLogBleReportViewModel.uploadLog(mContext, macID)
}
- (mFragments[2] as MapV3Fragment).showPetNameAndHead(mSelectPetPosition)
} else {
onChangeClick(mSelectPetPosition)
when (mViewBinding.homeV2ViewPager2.currentItem) {
@@ -364,6 +369,7 @@ class HomeV2Activity : BaseActivity(ActivityHomeV2Binding
}
}
}
+ (mFragments[2] as MapV3Fragment).showPetNameAndHead(mSelectPetPosition)
}
}
@@ -406,7 +412,7 @@ class HomeV2Activity : BaseActivity(ActivityHomeV2Binding
* 选择宠物弹窗
*/
fun selectPetDialog() {
- if (isRequestPetData && mPetList.size == 0) {
+ if (mPetList.size == 0) {
showToast(R.string.no_bind_pet)
return
}
diff --git a/app/src/main/java/com/abbidot/tracker/ui/activity/map/LiveActivityV3.kt b/app/src/main/java/com/abbidot/tracker/ui/activity/map/LiveActivityV3.kt
new file mode 100644
index 0000000..274b2ad
--- /dev/null
+++ b/app/src/main/java/com/abbidot/tracker/ui/activity/map/LiveActivityV3.kt
@@ -0,0 +1,1030 @@
+package com.abbidot.tracker.ui.activity.map
+
+import android.content.Intent
+import android.graphics.Typeface
+import android.view.View
+import android.widget.RelativeLayout
+import androidx.activity.viewModels
+import androidx.core.view.isGone
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.commit
+import androidx.lifecycle.lifecycleScope
+import com.abbidot.baselibrary.constant.ConState
+import com.abbidot.baselibrary.constant.EventName
+import com.abbidot.baselibrary.constant.MMKVKey
+import com.abbidot.baselibrary.eventbus.XEventBus
+import com.abbidot.baselibrary.list.BaseRecyclerAdapter
+import com.abbidot.baselibrary.util.AppUtils
+import com.abbidot.baselibrary.util.LogUtil
+import com.abbidot.baselibrary.util.MMKVUtil
+import com.abbidot.baselibrary.util.Utils
+import com.abbidot.tracker.R
+import com.abbidot.tracker.adapter.HomeMapDeviceStateAdapter
+import com.abbidot.tracker.base.BaseActivity
+import com.abbidot.tracker.base.BaseDialog
+import com.abbidot.tracker.bean.BleReportDataBean
+import com.abbidot.tracker.bean.BleTrackDeviceBean
+import com.abbidot.tracker.bean.DataBean
+import com.abbidot.tracker.bean.HistoryDataBean
+import com.abbidot.tracker.bean.LiveDataBean
+import com.abbidot.tracker.bean.MapDeviceBean
+import com.abbidot.tracker.bean.PetBean
+import com.abbidot.tracker.bean.ReceiveDeviceData
+import com.abbidot.tracker.constant.ConstantInt
+import com.abbidot.tracker.constant.ConstantString
+import com.abbidot.tracker.constant.GetResultCallback
+import com.abbidot.tracker.databinding.ActivityLiveV3Binding
+import com.abbidot.tracker.deprecated.ui.activity.vm.LedLightViewModel
+import com.abbidot.tracker.dialog.CommonDialog1
+import com.abbidot.tracker.dialog.SelectMapTypeDialog
+import com.abbidot.tracker.ui.DebugActivity
+import com.abbidot.tracker.ui.common.map.HomeMapCommonV3
+import com.abbidot.tracker.util.Util
+import com.abbidot.tracker.util.ViewUtil
+import com.abbidot.tracker.util.bluetooth.SRBleCmdUtil
+import com.abbidot.tracker.util.bluetooth.SRBleUtil
+import com.abbidot.tracker.vm.ConnectionDeviceViewModel
+import com.abbidot.tracker.vm.CountDownTimerViewModel
+import com.abbidot.tracker.vm.FencesMapViewModel
+import com.abbidot.tracker.vm.FindBleDeviceViewModel
+import com.abbidot.tracker.vm.MapLiveViewModel
+import com.abbidot.tracker.vm.MapViewModel
+import com.clj.fastble.BleManager
+import com.daimajia.androidanimations.library.Techniques
+import com.daimajia.androidanimations.library.YoYo
+import dagger.hilt.android.AndroidEntryPoint
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+import javax.inject.Inject
+
+@AndroidEntryPoint
+class LiveActivityV3 : BaseActivity(ActivityLiveV3Binding::inflate) {
+
+ private val mFencesMapViewModel: FencesMapViewModel by viewModels()
+ private val mMapViewModel: MapViewModel by viewModels()
+ private val mFindBleDeviceViewModel: FindBleDeviceViewModel by viewModels()
+ private val mMapLiveViewModel: MapLiveViewModel by viewModels()
+ private val mLedLightViewModel: LedLightViewModel by viewModels()
+ private val mCountDownViewModel: CountDownTimerViewModel by viewModels()
+ private val mConDeviceViewModel: ConnectionDeviceViewModel by viewModels()
+
+ private var mSelectMapTypeDialog: SelectMapTypeDialog? = null
+
+ private lateinit var mDeviceStateList: MutableList
+ private lateinit var mDeviceStateAdapter: HomeMapDeviceStateAdapter
+
+ @Inject
+ lateinit var mHomeMapCommon: HomeMapCommonV3
+ private lateinit var mFragment: Fragment
+
+ private var mMapDeviceBean: MapDeviceBean? = null
+
+ //启动动画移动地图摄像机
+ private var isMoveCamera = true
+
+ //是否显示围栏
+ private var isShowFence = true
+
+ //地图类型,标准和卫星地图
+ private var mMapType = ConstantInt.Type0
+ private var mShowCenterLocation = ConstantInt.PetLocationType
+
+ //是否是直播跳转
+ private var isLiveJump = true
+ private var mLiveStatus = 1
+ private var mPetBean: PetBean? = null
+ private var mTrackBleDevice: BleTrackDeviceBean? = null
+
+ //直播是否开始
+ private var isStartLive = false
+
+ // private val mLiveStateTips = mutableListOf(
+// R.string.txt_starting_live, R.string.txt_con_network, R.string.txt_gps_position
+// )
+ private var mStartLiveIndex = 0
+
+ //直播时间 分钟
+ private var mLiveTime = 5
+ private lateinit var mSpeedUnit: String
+ private lateinit var mDistanceUnit: String
+
+ //是否打开了找设备的声音
+ private var isOpenSound = false
+
+ //设备Led灯开关
+ private var isLedOpen = false
+ private var mRequestModeType = ConstantInt.Type1
+
+ override fun getTopBar() = null
+
+ override fun initData() {
+ super.initData()
+ mSpeedUnit = Util.getMetricUnits(mContext, ConstantInt.Type2)
+ mDistanceUnit = Util.getMetricUnits(mContext, ConstantInt.Type3)
+ intent.extras?.apply {
+ isLiveJump = getBoolean(ConstantString.JumpActivity, true)
+ mPetBean = Util.getParcelableAdaptive(intent, ConstantString.Pet, PetBean::class.java)
+ }
+
+ isShowFence = Util.getShowFenceSp()
+
+ mViewBinding.apply {
+ ilLiveV2BluetoothFindDevice.ivMapLiveV2BleConState.setValue(0)
+ mFragment = mHomeMapCommon.getMapFragment(
+ mContext,
+ ilLiveV3MapPetLocation,
+ llLiveV3MapDeviceBatteryLayout,
+ Utils.DATE_FORMAT_PATTERN_EN12
+ ) { mapLoadOk() }
+ ViewUtil.instance.setMapSwitchLocationButtonImage(
+ ivMapLiveV2RefreshBtn, mShowCenterLocation
+ )
+ ilLiveV2OperateLayout.tvLiveV2Speed.text = "--$mSpeedUnit"
+ ilLiveV2OperateLayout.tvLiveV2Distance.text = "--$mDistanceUnit"
+ llLiveV2MapTopPet.ivTopPetBtnSmall.setImageResource(R.drawable.icon_map_type)
+ lavLiveV2StateAnim.let {
+ it.setAnimation("lottie/loading_dog.json")
+ it.playAnimation()
+ }
+
+ mDeviceStateList = mutableListOf()
+ mMapViewModel.addDeviceDefaultStateData(mContext, mDeviceStateList)
+ mDeviceStateAdapter = HomeMapDeviceStateAdapter(mContext, mDeviceStateList)
+ ViewUtil.instance.setRecyclerViewVerticalLinearLayout(
+ mContext, rvMapLiveV2DeviceState, mDeviceStateAdapter, bottom = 10
+ )
+ ilLiveV2BluetoothFindDevice.liveV2BluetoothSignal.setValue(0)
+ ilLiveV2BluetoothFindDevice.findBleDeviceRadoView.setValue(0)
+
+ setOnClickListenerViews(
+ ilLiveV2OperateLayout.llLiveV2StopLive,
+ ivMapLiveV2RefreshBtn,
+ ivMapLiveV2BluetoothBtn,
+ ilLiveV2BluetoothFindDevice.btnLiveV2StopRadar,
+ llLiveV2MapTopPet.ivTopPetBtnSmall,
+ ilLiveV2OperateLayout.ilLiveV2DataLightSwitch.root,
+ ilLiveV2OperateLayout.ilLiveV2DataLightSwitch.cbDeviceLightSwitch,
+ ilLiveV2BluetoothFindDevice.ilLiveV2RadarLightSwitch.cbDeviceLightSwitch,
+ ilLiveV2BluetoothFindDevice.ilLiveV2RadarLightSwitch.root,
+ ilLiveV2BluetoothFindDevice.ivLiveV2FindDeviceSound,
+ ilLiveV2OperateLayout.btnLiveV2Issue,
+ ilMapLiveV2IssueLayout.tvCloseIssueBtn,
+ ilLiveV3MapDeviceBatteryLayout.ivDeviceCloseBtn,
+ ilLiveV3MapDeviceMsg.ivDeviceMsgCloseBtn
+ )
+
+ supportFragmentManager.commit {
+ add(R.id.fc_live_v2_map_fragment, mFragment)
+ }
+
+ mPetBean?.let { pet ->
+ if (!isLiveJump) {
+ findBleDevice(pet.macID)
+ llLiveV2StateLayout.visibility = View.GONE
+ }
+
+ if (AppUtils.isDebug()) {
+ llLiveV2MapTopPet.homeDataPetHeadSmall.root.setOnLongClickListener {
+ goToDebugActivity(pet)
+ true
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * 地图加载好了
+ */
+ private fun mapLoadOk() {
+ showPetNameAndHead()
+ }
+
+ override fun liveDataObserve() {
+ mCountDownViewModel.mCountDownEndLiveData.observe(this) {
+ when (mStartLiveIndex) {
+// 0 -> {
+// mStartLiveIndex++
+// //显示Connecting to network 30秒
+// mViewBinding.tvLiveV2StateContent.setText(mLiveStateTips[mStartLiveIndex])
+// mCountDownViewModel.startCountDown(30)
+// }
+//
+// 1 -> {
+// mStartLiveIndex++
+// //显示GPS positioning
+// mCountDownViewModel.startCountDown(3 * 60)
+// mViewBinding.tvLiveV2StateContent.setText(mLiveStateTips[mStartLiveIndex])
+// }
+//
+// 2 -> {
+// if (isStartLive) {
+// mStartLiveIndex++
+// //显示Starting 5-min Live
+// val str = String.format(getString(R.string.txt_start_min_live), mLiveTime)
+// mViewBinding.tvLiveV2StateContent.text = str
+// mCountDownViewModel.startCountDown(2)
+// } else {
+// //直播超时
+// mLiveStatus = -1
+// stopLive()
+// }
+// }
+//
+ 2 -> {
+ mViewBinding.llLiveV2StateLayout.visibility = View.VISIBLE
+ mStartLiveIndex++
+ //显示Starting 5-min Live
+ val str = String.format(getString(R.string.txt_start_min_live), "$mLiveTime")
+ mViewBinding.tvLiveV2StateContent.text = str
+ mCountDownViewModel.startCountDown(5)
+ }
+
+ 3 -> mViewBinding.llLiveV2StateLayout.visibility = View.GONE
+ }
+ }
+ //获取当前宠物位置和围栏信息
+ mMapViewModel.mMapDeviceLiveData.observe(this) {
+ dealRequestResult(it, object : GetResultCallback {
+ override fun onResult(any: Any) {
+ val data = it.getOrNull()
+ data?.apply {
+ mMapDeviceBean = data
+ setMapData(data)
+ mMapViewModel.setDeviceStateAndWarningData(
+ mContext,
+ mPetBean,
+ data,
+ mViewBinding.ilLiveV3MapDeviceMsg.root,
+ mViewBinding.ilLiveV3MapDeviceMsg.tvDeviceMsgContent,
+ mViewBinding.ilLiveV3MapDeviceMsg.ivDeviceMsgCloseBtn,
+ mDeviceStateList,
+ mDeviceStateAdapter
+ )
+ }
+ }
+
+ override fun onRequestError(exceptionCode: String?) {
+ LogUtil.e("LiveV2Activity获取当前宠物位置和围栏信息onRequestError,再次请求")
+ if (exceptionCode == mNetworkRequestsFailLimit) {
+ finish()
+ } else {
+ mPetBean?.apply {
+ //获取首页设备信息状态
+ mMapViewModel.getMapDeviceStatus(deviceId, false)
+ }
+ }
+ }
+ }, showLoading = false)
+ }
+
+ mMapLiveViewModel.mMapLiveStatusLiveData.observe(this) {
+ dealRequestResult(it, object : GetResultCallback {
+ override fun onResult(any: Any) {
+ mPetBean?.apply {
+// SRBleUtil.instance.isConnectBleSendNotifyData(macID)
+ when (mLiveStatus) {
+ //直播超时
+ -1 -> {
+ XEventBus.post(EventName.LiveOpenTimeOut)
+ finish()
+ }
+ //直播结束
+ 0 -> {
+ mViewBinding.llLiveV2StateLayout.visibility = View.GONE
+// showToast(R.string.txt_change_successful, true)
+ finish()
+ }
+ //直播开始
+ else -> {
+ //直播开启后,就去获取直播轨迹
+ if (!BleManager.getInstance().isConnected(macID)) {
+ mMapLiveViewModel.mGetPetLivePointTimeStamp =
+ System.currentTimeMillis() / 1000
+ mMapLiveViewModel.getPetLivePoint(deviceId)
+ }
+ }
+ }
+ }
+ }
+
+ override fun onRequestError(exceptionCode: String?) {
+ LogUtil.e("HomeV2Activity直播开启错误onRequestError,再次请求")
+ if (exceptionCode == mNetworkRequestsFailLimit) {
+ finish()
+ } else {
+ mPetBean?.apply {
+ mMapLiveViewModel.setupDeviceLiveStatus(
+ this@LiveActivityV3, deviceId, mLiveStatus, mRequestModeType
+ )
+ }
+ }
+ }
+ })
+ }
+
+ //获取直播轨迹
+ mMapLiveViewModel.mMapLiveLiveData.observe(this) {
+ mHomeMapCommon.startRefreshUserLocation()
+ dealRequestResult(it, object : GetResultCallback {
+ override fun onResult(any: Any) {
+ it.getOrNull()?.apply {
+ setTrackData(this)
+ }
+ }
+ }, isShowRequestErrorTip = false)
+ }
+
+ //接收蓝牙连接状态
+ XEventBus.observe(this, EventName.ConnectDeviceState) { trackBle: BleTrackDeviceBean ->
+ mPetBean?.apply {
+ if (trackBle.mac == macID && trackBle.conState != ConState.CONNECTED) {
+ //隐藏蓝牙nearby
+ mViewBinding.ilLiveV3MapDeviceMsg.root.visibility = View.GONE
+ }
+ }
+ mMapDeviceBean?.apply {
+ if (trackBle.mac == deviceMacId) {
+ updateConState(trackBle)
+ }
+ }
+ }
+ //搜索蓝牙的设备状态
+ XEventBus.observe(this, EventName.ActionConDeviceState) { conState: Int ->
+ if (conState == ConState.DEVICE_NOT_FOUND) {
+ openNetLive(ConstantInt.Type2)
+ }
+ }
+
+ mLedLightViewModel.mLedSwitchLiveData.observe(this) {
+ dealRequestResult(it, object : GetResultCallback {
+ override fun onResult(any: Any) {
+// mViewBinding.cbLiveV2DeviceLightSwitch.isChecked =
+// !mViewBinding.cbLiveV2DeviceLightSwitch.isChecked
+// showToast(R.string.txt_please_wait)
+ }
+ })
+ }
+
+ //蓝牙上报的数据
+ XEventBus.observe(this, EventName.BleReportData) { reportData: BleReportDataBean ->
+ mPetBean?.apply {
+ if (macID == reportData.mac) updateBleReportData(reportData)
+ }
+ }
+
+ //接收发送指令后设备返回的数据
+ XEventBus.observe(this, EventName.DeviceReceiveData) { receiveData: ReceiveDeviceData ->
+ mPetBean?.apply {
+ if (macID == receiveData.mac) {
+ val data = receiveData.data
+ parseData(data)
+ }
+ }
+ }
+ }
+
+
+ /**
+ * 跳转debug调试页面
+ */
+ private fun goToDebugActivity(petBean: PetBean) {
+ val intent = Intent(mContext, DebugActivity::class.java)
+ ArrayList().apply {
+ add(petBean)
+ intent.putParcelableArrayListExtra(ConstantString.Pet, this)
+ }
+ intent.putExtra(ConstantString.Index, 0)
+ startActivity(intent)
+ }
+
+ /**
+ * 解析蓝牙返回的数据
+ */
+ private fun parseData(data: ByteArray?) {
+ if (null != data && data.isNotEmpty()) {
+ val data0 = SRBleCmdUtil.instance.byteToInt(data[0])
+ val data1 = SRBleCmdUtil.instance.byteToInt(data[1])
+ val data2 = SRBleCmdUtil.instance.byteToInt(data[2])
+ if (data0 == 0x06 && data1 == 1) {
+ val data3 = SRBleCmdUtil.instance.byteToInt(data[3])
+ //开启直播
+ if (data2 == 1) {
+ if (data3 == 0) {
+ LogUtil.e("蓝牙开启直播成功")
+ mPetBean?.apply {
+ mRequestModeType = ConstantInt.Type1
+ mMapLiveViewModel.setupDeviceLiveStatus(
+ this@LiveActivityV3, deviceId, mLiveStatus, mRequestModeType
+ )
+ }
+ } else {
+ LogUtil.e("蓝牙开启直播失败")
+ openNetLive(ConstantInt.Type3)
+ }
+ } else if (data2 == 0) {
+ mPetBean?.apply {
+ //停止Live直播
+ mRequestModeType = if (data3 == 0) {
+ LogUtil.e("蓝牙停止直播成功")
+ ConstantInt.Type1
+ } else {
+ LogUtil.e("蓝牙停止直播失败")
+ ConstantInt.Type3
+ }
+ mMapLiveViewModel.setupDeviceLiveStatus(
+ this@LiveActivityV3, deviceId, 0, mRequestModeType
+ )
+ }
+ }
+ } else if (data0 == 3 && data1 == 1) {
+ val modeType = if (data2 == 0) {
+ ConstantInt.Type1
+ } else {
+ ConstantInt.Type3
+ }
+ mMapDeviceBean?.apply {
+ mLedLightViewModel.setLedSwitch(
+ null, deviceServerId, ledSwitch, modeType
+ )
+ }
+ }
+ }
+ }
+
+ /**
+ * 开启网络上报直播
+ */
+ private fun openNetLive(modeType: Int) {
+ if (isLiveJump) {
+ mPetBean?.apply {
+ //刚开始显示Starting Live.
+ mCountDownViewModel.startCountDown(2)
+ mRequestModeType = modeType
+ mMapLiveViewModel.setupDeviceLiveStatus(
+ this@LiveActivityV3, deviceId, mLiveStatus, modeType
+ )
+ }
+ }
+ }
+
+ /**
+ * 更新蓝牙上报的数据
+ */
+ private fun updateBleReportData(bleReportDataBean: BleReportDataBean) {
+ mHomeMapCommon.startRefreshUserLocation()
+ bleReportDataBean.apply {
+ if (haveDeviceStateData) {
+ if (null == mMapDeviceBean) mMapDeviceBean = MapDeviceBean()
+ mMapDeviceBean?.let {
+ Util.bleReportDataToMapDevice(it, bleReportDataBean)
+
+ val isOpen = ledSwitch > ConstantInt.Close
+ mViewBinding.ilLiveV2OperateLayout.ilLiveV2DataLightSwitch.cbDeviceLightSwitch.isChecked =
+ isOpen
+ mViewBinding.ilLiveV2BluetoothFindDevice.ilLiveV2RadarLightSwitch.cbDeviceLightSwitch.isChecked =
+ isOpen
+
+// if (haveLocationData && liveFlag == ConstantInt.Type1) {
+ if (liveFlag == ConstantInt.Type1) {
+ if (!isStartLive) {
+ isStartLive = true
+ liveStartTip()
+ }
+ if (haveLocationData) {
+ lifecycleScope.launch {
+ locationList?.let { location ->
+ liveDrawLines(location)
+ }
+ }
+ }
+ setMapDeviceBean(it)
+ } else if (liveFlag == ConstantInt.Type0) {
+ //直播自动结束
+ if (isStartLive) {
+ XEventBus.post(EventName.LiveAutoEnd)
+ finish()
+ }
+ }
+
+ mMapViewModel.setDeviceStateAndWarningData(
+ mContext,
+ mPetBean,
+ it,
+ mViewBinding.ilLiveV3MapDeviceMsg.root,
+ mViewBinding.ilLiveV3MapDeviceMsg.tvDeviceMsgContent,
+ mViewBinding.ilLiveV3MapDeviceMsg.ivDeviceMsgCloseBtn,
+ mDeviceStateList,
+ mDeviceStateAdapter
+ )
+ }
+ }
+ }
+ }
+
+ /**
+ * 远程设置led开关
+ */
+ private fun setLedSwitch() {
+ isLedOpen = !isLedOpen
+ mViewBinding.apply {
+ //屏蔽点击就变状态
+// cbLiveV2DeviceLightSwitch.isChecked = !cbLiveV2DeviceLightSwitch.isChecked
+ ilLiveV2OperateLayout.ilLiveV2DataLightSwitch.cbDeviceLightSwitch.isChecked = isLedOpen
+ ilLiveV2BluetoothFindDevice.ilLiveV2RadarLightSwitch.cbDeviceLightSwitch.isChecked =
+ isLedOpen
+ val ledSwitch = if (isLedOpen) ConstantInt.Open
+ else ConstantInt.Close
+
+ mMapDeviceBean?.apply {
+ this.ledSwitch = ledSwitch
+ if (BleManager.getInstance().isConnected(deviceMacId)) {
+ setLedSwitch(ledSwitch)
+ } else {
+ mLedLightViewModel.setLedSwitch(
+ null, deviceServerId, ledSwitch, ConstantInt.Type2
+ )
+ }
+ }
+ }
+ }
+
+ /**
+ *发送设备开启关闭led蓝牙指令
+ */
+ private fun setLedSwitch(mode: Int) {
+ mTrackBleDevice?.apply {
+ SRBleUtil.instance.setBleLedSwitch(mContext, bleDevice, mode)
+ }
+ }
+
+ /**
+ * 更新设备连接状态
+ */
+ private fun updateConState(trackBleDevice: BleTrackDeviceBean) {
+ mTrackBleDevice = trackBleDevice
+ if (trackBleDevice.conState == ConState.CONNECTED) {
+ LogUtil.e("更新设备连接状态")
+ if (isLiveJump) {
+ if (isStartLive) {
+ mMapLiveViewModel.stopGetData()
+ } else {
+ mCountDownViewModel.startCountDown(2)
+ lifecycleScope.launch {
+ //延时几秒发送消息
+ delay(1000)
+ trackBleDevice.apply {
+ SRBleUtil.instance.writeData(
+ bleDevice, SRBleCmdUtil.instance.setLiveSwitch(1, mLiveTime * 60L)
+ )
+ }
+ }
+ }
+ }
+// showToast(R.string.tracker_manage_set_ble_connect)
+// mViewBinding.ilLiveV2BluetoothFindDevice.ivMapLiveV2BleConState.setValue(2)
+ } else if (trackBleDevice.conState == ConState.CONNECTION_FAIL) {
+ if (isLiveJump) {
+ openNetLive(ConstantInt.Type2)
+ }
+ } else {
+ if (isLiveJump && isStartLive) {
+ mPetBean?.apply {
+ //直播开启后,就去获取直播轨迹
+ mMapLiveViewModel.mGetPetLivePointTimeStamp = System.currentTimeMillis() / 1000
+ mMapLiveViewModel.getPetLivePoint(deviceId)
+ }
+ }
+ }
+ }
+
+
+ /**
+ * 显示地图类型选择弹窗
+ */
+ private fun showMapTypeDialog() {
+ if (null == mSelectMapTypeDialog) {
+ mSelectMapTypeDialog = ViewUtil.instance.getMapTypeDialog(
+ mContext, object : BaseRecyclerAdapter.OnItemClickListener {
+ override fun onItemClick(itemView: View?, pos: Int) {
+ mMapType = Util.getMapTypeSp()
+ if (pos == mMapType) {
+ return
+ }
+ mHomeMapCommon.switchSatelliteAndNormalMapType()
+ }
+ }) { v, isChecked ->
+ if (v.id == R.id.cb_dialog_map_fences_switch) {
+ isShowFence = isChecked
+ MMKVUtil.putBoolean(MMKVKey.ShowFence, isChecked)
+ if (isChecked) {
+ mMapDeviceBean?.fences?.let { fences ->
+ mFencesMapViewModel.setFencesData(mContext, fences, mFragment)
+ }
+ } else {
+ mFencesMapViewModel.setFencesData(mContext, null, mFragment)
+ }
+ }
+ }
+ } else {
+ mSelectMapTypeDialog!!.mapTypeSpToUpdate()
+ }
+ mSelectMapTypeDialog?.show()
+ }
+
+ /**
+ * 设置地图相关数据
+ */
+ private fun setMapData(mapDeviceBean: MapDeviceBean) {
+ mapDeviceBean.apply {
+ mLiveTime = liveTime / 60
+
+ mPetBean?.apply {
+ //查找是否连接了蓝牙
+ val bleConDevice = SRBleUtil.instance.getConnectMacDevice(macID)
+ if (null == bleConDevice) {
+ if (isLiveJump) {
+ //没有连接,一进入页面就尝试连接
+ if (SRBleUtil.instance.isBleEnable(mContext)) {
+ mConDeviceViewModel.connectDeviceToMac(this@LiveActivityV3, macID)
+ } else {
+ openNetLive(ConstantInt.Type2)
+ }
+ }
+ } else {
+ updateConState(bleConDevice)
+ }
+ }
+
+ mViewBinding.let {
+ isLedOpen = ledSwitch == ConstantInt.Open
+ it.ilLiveV2OperateLayout.ilLiveV2DataLightSwitch.cbDeviceLightSwitch.isChecked =
+ isLedOpen
+ it.ilLiveV2BluetoothFindDevice.ilLiveV2RadarLightSwitch.cbDeviceLightSwitch.isChecked =
+ isLedOpen
+// it.tvLiveV2Speed.text = String.format(
+// getString(R.string.txt_mph_unit),
+// Utils.formatDecimal(Util.kmhToMph(speed.toDouble()))
+// )
+ }
+
+ if (isShowFence) {
+ fences?.let { fences ->
+ mFencesMapViewModel.setFencesData(mContext, fences, mFragment)
+ }
+ }
+
+ mHomeMapCommon.let {
+ setMapDeviceBean(this)
+ it.refreshPetCurrentLocation(latitude, longitude, isMoveCamera)
+ it.startRippleCircleAnim()
+ isMoveCamera = false
+// val userAndPetDistance = it.getUserAndPetDistance()
+// mViewBinding.tvLiveV2Distance.text = String.format(
+// getString(R.string.txt_ft_unit), Utils.formatDecimal(userAndPetDistance)
+// )
+ }
+ }
+ }
+
+ private fun setMapDeviceBean(mapDeviceBean: MapDeviceBean) {
+ mapDeviceBean.apply {
+ mViewBinding.ilLiveV3MapDeviceBatteryLayout.let {
+ mMapViewModel.setMapDeviceBattery(
+ mContext, mapDeviceBean, it.root, it.tvDeviceBatteryInfo, it.ivDeviceCloseBtn
+ )
+ }
+ mViewBinding.ilLiveV3MapPetLocation.let {
+ mMapViewModel.setPetLocationReverseGeocode(
+ mContext, mapDeviceBean, it.root, it.tvPetLocationReverseGeocode
+ )
+ }
+ mHomeMapCommon.setMapDeviceBean(this)
+ }
+ }
+
+
+ /**
+ * 显示选择宠物弹窗
+ */
+ private fun showPetNameAndHead() {
+ mPetBean?.apply {
+ showLoading(true)
+ mViewBinding.llLiveV2MapTopPet.homeDataPetNameSmall.let {
+ it.text = petName
+ it.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0)
+ }
+ mViewBinding.llLiveV2MapTopPet.homeDataPetHeadSmall.appHeadImage.let {
+ ViewUtil.instance.setPetTypeHead(it, imgurl, petType)
+ ViewUtil.instance.viewAlphaAndRotationObjectAnimator(it)
+ }
+ //重新设置地图宠物头像
+ mHomeMapCommon.setPetHeadIcon(imgurl, petType)
+
+ //获取首页设备信息状态
+ mMapViewModel.getMapDeviceStatus(deviceId, false)
+ }
+ }
+
+ private fun setTrackData(liveDataBean: LiveDataBean) {
+ //测试经纬度移动
+// mFencesViewModel.setFencesData(mContext!!, isInFence, mFencesList, mFragment)
+
+ mViewBinding.apply {
+
+ liveDataBean.deviceInfo?.apply {
+ if (liveFlag == ConstantInt.Type0) {
+ //直播自动结束
+ if (isStartLive) {
+ XEventBus.post(EventName.LiveAutoEnd)
+ finish()
+ }
+ return
+ } else if (liveFlag == ConstantInt.Type1) {
+ if (!isStartLive) {
+ liveStartTip()
+ isStartLive = true
+ }
+ }
+
+ val speedStr = Util.metricConvertUnits(
+ speed, ConstantInt.Type2, 2
+ ).toString() + mSpeedUnit
+ ilLiveV2OperateLayout.tvLiveV2Speed.text = speedStr
+
+ setMapDeviceBean(this)
+ val isOpen = ledSwitch == ConstantInt.Open
+ ilLiveV2OperateLayout.ilLiveV2DataLightSwitch.cbDeviceLightSwitch.isChecked = isOpen
+ ilLiveV2BluetoothFindDevice.ilLiveV2RadarLightSwitch.cbDeviceLightSwitch.isChecked =
+ isOpen
+ mMapViewModel.setDeviceStateAndWarningData(
+ mContext,
+ mPetBean,
+ this,
+ mViewBinding.ilLiveV3MapDeviceMsg.root,
+ mViewBinding.ilLiveV3MapDeviceMsg.tvDeviceMsgContent,
+ mViewBinding.ilLiveV3MapDeviceMsg.ivDeviceMsgCloseBtn,
+ mDeviceStateList,
+ mDeviceStateAdapter
+ )
+
+ liveDataBean.livePoints?.apply {
+ if (size > 0) {
+ mMapLiveViewModel.mGetPetLivePointTimeStamp =
+ System.currentTimeMillis() / 1000
+ //只有一个点的时候,不用休眠
+ val sleepTime =
+ if (size - 1 > 0) mMapLiveViewModel.mRefreshTime / (size - 1) * 1000L
+ else 0
+ lifecycleScope.launch {
+ forEach {
+ liveDrawLine(it.latitude, it.longitude)
+ //休眠几秒再画线
+ if (sleepTime > 0) delay(sleepTime)
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * 直播开始提示
+ */
+ private fun liveStartTip() {
+ LogUtil.e("直播开始了")
+ if (mStartLiveIndex == 0) {
+ mStartLiveIndex = 2
+ //直播开始显示Starting 5-min Live
+ mCountDownViewModel.startCountDown(1)
+ mHomeMapCommon.greenRippleCircleAnim()
+ }
+ }
+
+ /**
+ * 直播画线
+ */
+ private fun liveDrawLine(latitude: Double, longitude: Double) {
+ mHomeMapCommon.addTrackLine(latitude, longitude)
+ val userAndPetDistance = mHomeMapCommon.getUserAndPetDistance()
+ val distanceStr = Util.metricConvertUnits(
+ userAndPetDistance.toFloat(), ConstantInt.Type3, 2
+ ).toString() + mDistanceUnit
+ mViewBinding.ilLiveV2OperateLayout.tvLiveV2Distance.text = distanceStr
+ }
+
+ /**
+ * 直播画线
+ */
+ private fun liveDrawLines(trackList: MutableList) {
+ mHomeMapCommon.addTrackLines(trackList)
+ val userAndPetDistance = mHomeMapCommon.getUserAndPetDistance()
+ val distanceStr = Util.metricConvertUnits(
+ userAndPetDistance.toFloat(), ConstantInt.Type3, 2
+ ).toString() + mDistanceUnit
+ mViewBinding.ilLiveV2OperateLayout.tvLiveV2Distance.text = distanceStr
+ }
+
+ /**
+ * 显示隐藏找蓝牙设备布局
+ */
+ private fun showAndHideFindLayout() {
+ mViewBinding.apply {
+ ilLiveV3MapPetLocation.root.visibility = View.GONE
+ val relativeLayout = ivMapLiveV2RefreshBtn.layoutParams as RelativeLayout.LayoutParams
+ ivMapLiveV2RefreshBtn.visibility = View.GONE
+ if (ilLiveV2BluetoothFindDevice.root.isGone) {
+ //找蓝牙设备布局显示
+ YoYo.with(Techniques.BounceInUp).duration(800).onStart {
+ ilLiveV2OperateLayout.root.visibility = View.GONE
+ ilLiveV2BluetoothFindDevice.root.visibility = View.VISIBLE
+ }.onEnd {
+ //刷新定位按钮显示动画
+ ViewUtil.instance.viewShowFadeInAnimation(ivMapLiveV2RefreshBtn)
+ }.playOn(ilLiveV2BluetoothFindDevice.root)
+
+ ivMapLiveV2BluetoothBtn.visibility = View.GONE
+ relativeLayout.removeRule(RelativeLayout.ALIGN_PARENT_BOTTOM)
+ relativeLayout.addRule(RelativeLayout.ABOVE, R.id.il_live_v2_bluetooth_find_device)
+ } else {
+ //找蓝牙设备布局退出
+ YoYo.with(Techniques.SlideOutDown).duration(600).onEnd {
+ ilLiveV2BluetoothFindDevice.root.visibility = View.GONE
+ ilLiveV2OperateLayout.root.visibility = View.VISIBLE
+ }.playOn(ilLiveV2BluetoothFindDevice.root)
+ //直播操作按钮布局显示
+ YoYo.with(Techniques.BounceInUp).duration(800).delay(400).onEnd {
+ //蓝牙图标按钮显示动画
+ ViewUtil.instance.viewShowFadeInAnimation(ivMapLiveV2BluetoothBtn)
+ //刷新定位按钮显示动画
+ ViewUtil.instance.viewShowFadeInAnimation(ivMapLiveV2RefreshBtn)
+ }.playOn(ilLiveV2OperateLayout.root)
+
+ relativeLayout.removeRule(RelativeLayout.ABOVE)
+ relativeLayout.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM)
+ }
+
+ root.postDelayed({
+ ilLiveV3MapPetLocation.root.visibility = View.VISIBLE
+ mHomeMapCommon.setMarkerInfoViewOffset()
+ }, 1000)
+ }
+ }
+
+ /**
+ * 显示直播问题
+ */
+ private fun showLiveIssue() {
+ mViewBinding.apply {
+ ilLiveV3MapPetLocation.root.visibility = View.GONE
+ if (ilMapLiveV2IssueLayout.root.isGone) {
+ YoYo.with(Techniques.BounceInUp).duration(700).onStart {
+ ilLiveV2OperateLayout.root.visibility = View.GONE
+ ilMapLiveV2IssueLayout.root.visibility = View.VISIBLE
+ }.playOn(ilMapLiveV2IssueLayout.root)
+ } else {
+ YoYo.with(Techniques.SlideOutDown).duration(600).onEnd {
+ ilMapLiveV2IssueLayout.root.visibility = View.GONE
+ YoYo.with(Techniques.BounceInUp).duration(600).onStart {
+ ilLiveV2OperateLayout.root.visibility = View.VISIBLE
+ }.playOn(ilLiveV2OperateLayout.root)
+ }.playOn(ilMapLiveV2IssueLayout.root)
+ }
+
+ root.postDelayed({
+ ilLiveV3MapPetLocation.root.visibility = View.VISIBLE
+ mHomeMapCommon.setMarkerInfoViewOffset()
+ }, 1000)
+ }
+ }
+
+ /**
+ * 找蓝牙设备
+ */
+ private fun findBleDevice(mac: String) {
+ Util.checkBluetoothPermissionsEnabled(mContext, {
+ showAndHideFindLayout()
+ mViewBinding.ilLiveV2BluetoothFindDevice.apply {
+ mFindBleDeviceViewModel.startScanFind(
+ this@LiveActivityV3,
+ mac.uppercase(),
+ liveV2BluetoothSignal,
+ findBleDeviceRadoView,
+ ivMapLiveV2BleConState
+ )
+ }
+ })
+ }
+
+ override fun listenBackPressed() {
+ if (isLiveJump) stopMapLive()
+ else super.listenBackPressed()
+ }
+
+ private fun stopMapLive() {
+ CommonDialog1(
+ mContext,
+ "",
+ getString(R.string.txt_stop_live_tips),
+ false,
+ 5f,
+ Typeface.BOLD,
+ R.color.data_black_color,
+ canceledOnTouchOutside = true,
+ okClickListener = object : BaseDialog.OnDialogOkListener {
+ override fun onOkClick(dialog: BaseDialog<*>) {
+ mMapDeviceBean?.apply {
+ mLiveStatus = 0
+ stopLive()
+ }
+ }
+ }).show()
+ }
+
+ /**
+ * 停止直播
+ */
+ private fun stopLive() {
+ mPetBean?.apply {
+ setButtonEnabled(mViewBinding.ilLiveV2OperateLayout.llLiveV2StopLive, ConstantInt.Type0)
+ if (BleManager.getInstance().isConnected(macID)) {
+ SRBleUtil.instance.isConnectBleSendCmdData(
+ macID, SRBleCmdUtil.instance.setLiveSwitch(0, 0)
+ )
+ } else {
+ mRequestModeType = ConstantInt.Type2
+ mMapLiveViewModel.setupDeviceLiveStatus(
+ this@LiveActivityV3, mPetBean!!.deviceId, 0, mRequestModeType
+ )
+ }
+ }
+
+ }
+
+ /**
+ * 设置找设备声音音量
+ */
+ private fun setSound() {
+ if (isOpenSound) {
+ mFindBleDeviceViewModel.setVolume(0)
+ mViewBinding.ilLiveV2BluetoothFindDevice.ivLiveV2FindDeviceSound.setImageResource(R.drawable.icon_sound_off_svg)
+ } else {
+ mFindBleDeviceViewModel.setVolume(mFindBleDeviceViewModel.mMaxVolume)
+ mViewBinding.ilLiveV2BluetoothFindDevice.ivLiveV2FindDeviceSound.setImageResource(R.drawable.icon_sound_on_svg)
+ }
+ isOpenSound = !isOpenSound
+ }
+
+ override fun onClick(v: View?) {
+ mViewBinding.apply {
+ when (v!!) {
+ ivMapLiveV2RefreshBtn -> {
+ mShowCenterLocation = if (mShowCenterLocation == ConstantInt.PetLocationType) {
+ ConstantInt.UserLocationType
+ } else {
+ ConstantInt.PetLocationType
+ }
+ ViewUtil.instance.setMapSwitchLocationButtonImage(
+ ivMapLiveV2RefreshBtn, mShowCenterLocation
+ )
+ mHomeMapCommon.switchShowLocation(mShowCenterLocation)
+ }
+
+ ivMapLiveV2BluetoothBtn -> mPetBean?.apply {
+ findBleDevice(macID)
+ }
+
+ ilLiveV2BluetoothFindDevice.btnLiveV2StopRadar -> {
+ if (isLiveJump) {
+ isOpenSound = true
+ setSound()
+ showAndHideFindLayout()
+ } else {
+ mFindBleDeviceViewModel.stopFindDevice()
+ finish()
+ }
+ }
+
+ llLiveV2MapTopPet.ivTopPetBtnSmall -> showMapTypeDialog()
+ ilLiveV2OperateLayout.llLiveV2StopLive -> stopMapLive()
+ ilLiveV2OperateLayout.ilLiveV2DataLightSwitch.root, ilLiveV2OperateLayout.ilLiveV2DataLightSwitch.cbDeviceLightSwitch, ilLiveV2BluetoothFindDevice.ilLiveV2RadarLightSwitch.cbDeviceLightSwitch, ilLiveV2BluetoothFindDevice.ilLiveV2RadarLightSwitch.root -> setLedSwitch()
+
+ ilLiveV2OperateLayout.btnLiveV2Issue -> showLiveIssue()
+ ilMapLiveV2IssueLayout.tvCloseIssueBtn -> showLiveIssue()
+ ilLiveV2BluetoothFindDevice.ivLiveV2FindDeviceSound -> setSound()
+ ilLiveV3MapDeviceBatteryLayout.ivDeviceCloseBtn -> llLiveV3MapDeviceBatteryLayout.visibility =
+ View.INVISIBLE
+
+ ilLiveV3MapDeviceMsg.ivDeviceMsgCloseBtn -> ilLiveV3MapDeviceMsg.root.visibility =
+ View.GONE
+ }
+ }
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ mViewBinding.lavLiveV2StateAnim.cancelAnimation()
+// stopLive()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/abbidot/tracker/ui/common/map/HomeMapCommonV3.kt b/app/src/main/java/com/abbidot/tracker/ui/common/map/HomeMapCommonV3.kt
new file mode 100644
index 0000000..ad7e34a
--- /dev/null
+++ b/app/src/main/java/com/abbidot/tracker/ui/common/map/HomeMapCommonV3.kt
@@ -0,0 +1,199 @@
+package com.abbidot.tracker.ui.common.map
+
+import android.content.Context
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import com.abbidot.baselibrary.constant.MMKVKey
+import com.abbidot.baselibrary.util.AppUtils
+import com.abbidot.baselibrary.util.MMKVUtil
+import com.abbidot.tracker.base.BaseMapCommon
+import com.abbidot.tracker.bean.HistoryDataBean
+import com.abbidot.tracker.bean.MapDeviceBean
+import com.abbidot.tracker.constant.ConstantInt
+import com.abbidot.tracker.databinding.LayoutPetLocationInfoBinding
+import com.abbidot.tracker.ui.fragment.map.baidumap.HomeMapBaiduMapFragment
+import com.abbidot.tracker.ui.fragment.map.googlemap.HomeMapGoogleMapFragmentV3
+import com.google.android.gms.maps.model.LatLng
+import javax.inject.Inject
+
+/**
+ *Created by .yzq on 2022/7/5/005.
+ * @link
+ * @description:
+ */
+class HomeMapCommonV3 @Inject constructor() : BaseMapCommon() {
+
+ private var mHomeMapGoogleMapFragment: HomeMapGoogleMapFragmentV3? = null
+ private var mHomeMapBaiduMapFragment: HomeMapBaiduMapFragment? = null
+
+ fun getMapFragment(
+ context: Context,
+ locationLayoutViewBinding: LayoutPetLocationInfoBinding,
+ deviceBatteryLayout: ViewGroup,
+ petAddressTimeFormat: String,
+ mapLoadOk: () -> Unit
+ ): Fragment {
+ return if (AppUtils.isChina(AppUtils.SWITCH_MAP_TYPE)) {
+ mHomeMapBaiduMapFragment = HomeMapBaiduMapFragment.newInstance(context, mapLoadOk)
+ mHomeMapBaiduMapFragment!!
+ } else {
+ mHomeMapGoogleMapFragment = HomeMapGoogleMapFragmentV3.newInstance(
+ context,
+ locationLayoutViewBinding,
+ deviceBatteryLayout,
+ petAddressTimeFormat,
+ mapLoadOk
+ )
+ mHomeMapGoogleMapFragment!!
+ }
+ }
+
+ fun setMapDeviceBean(mapDeviceBean: MapDeviceBean?) {
+ if (null != mHomeMapBaiduMapFragment) {
+ mHomeMapBaiduMapFragment!!.setMapDeviceBean(mapDeviceBean)
+ } else if (null != mHomeMapGoogleMapFragment) {
+ mHomeMapGoogleMapFragment!!.setMapDeviceBean(mapDeviceBean)
+ }
+ }
+
+ /**
+ * 开始每隔几秒刷新用户位置
+ */
+ fun startRefreshUserLocation() {
+ if (isMapLoadOk()) startRefreshUserLocation(
+ mHomeMapBaiduMapFragment, mHomeMapGoogleMapFragment
+ )
+ }
+
+ /**
+ * 获取宠物反编译好的位置信息
+ */
+ fun getDecPetAddressData(): HistoryDataBean? {
+ if (null != mHomeMapBaiduMapFragment) {
+ return mHomeMapBaiduMapFragment!!.mDecPetAddressData
+ } else if (null != mHomeMapGoogleMapFragment) {
+ return mHomeMapGoogleMapFragment!!.mDecPetAddressData
+ }
+ return null
+ }
+
+ fun clearMarker() {
+ if (null != mHomeMapBaiduMapFragment) {
+ mHomeMapBaiduMapFragment!!.mBaiduMap?.clear()
+ } else if (null != mHomeMapGoogleMapFragment) {
+ mHomeMapGoogleMapFragment!!.clearAllMarker()
+ }
+ }
+
+ fun refreshPetCurrentLocation(latitude: Double, longitude: Double, isMoveCamera: Boolean) {
+ if (null != mHomeMapBaiduMapFragment) {
+ mHomeMapBaiduMapFragment?.apply {
+ refreshPetCurrentLocation(
+ latitude, longitude, isMoveCamera
+ )
+ }
+ } else if (null != mHomeMapGoogleMapFragment) {
+ MMKVUtil.putDouble(MMKVKey.MapShowDefaultLat, latitude)
+ MMKVUtil.putDouble(MMKVKey.MapShowDefaultLon, longitude)
+ mHomeMapGoogleMapFragment?.apply {
+ refreshPetCurrentLocation(
+ LatLng(latitude, longitude), needMoveCamera = isMoveCamera
+ )
+ }
+ }
+ }
+
+ /**
+ * 重新设置宠物头像
+ */
+ fun setPetHeadIcon(imageUrl: String, petType: Int) {
+ if (null != mHomeMapBaiduMapFragment) {
+ mHomeMapBaiduMapFragment!!.setPetHeadIconUrl(imageUrl)
+ } else if (null != mHomeMapGoogleMapFragment) {
+ mHomeMapGoogleMapFragment!!.setPetHeadIconUrl(imageUrl, petType)
+ }
+ }
+
+ /**
+ * 地图是否加载好了,准备好了
+ */
+ fun isMapLoadOk() = isMapLoadOk(mHomeMapBaiduMapFragment, mHomeMapGoogleMapFragment)
+
+ /**
+ * 切换地图类型
+ */
+ fun switchSatelliteAndNormalMapType() {
+ switchSatelliteAndNormalMapType(mHomeMapBaiduMapFragment, mHomeMapGoogleMapFragment)
+ }
+
+ /**
+ * 切换用户和宠物的位置居中显示
+ */
+ fun switchShowLocation(@ConstantInt type: Int) {
+ switchShowLocationType(type, mHomeMapBaiduMapFragment, mHomeMapGoogleMapFragment)
+ }
+
+ /**
+ * 画轨迹线
+ */
+ fun addTrackLine(latitude: Double, longitude: Double) {
+ if (null != mHomeMapBaiduMapFragment) {
+ mHomeMapBaiduMapFragment!!.addLine(latitude, longitude)
+ } else if (null != mHomeMapGoogleMapFragment) {
+ mHomeMapGoogleMapFragment!!.addLine(LatLng(latitude, longitude))
+ }
+ }
+
+ /**
+ * 画轨迹线
+ */
+ fun addTrackLines(trackList: MutableList) {
+ if (null != mHomeMapBaiduMapFragment) {
+ } else if (null != mHomeMapGoogleMapFragment) {
+ mHomeMapGoogleMapFragment!!.addLines(trackList)
+ }
+ }
+
+ /**
+ * 计算用户和宠物的距离
+ */
+ fun getUserAndPetDistance(): Double {
+ var distance = 0.0
+ if (null != mHomeMapBaiduMapFragment) {
+ distance = mHomeMapBaiduMapFragment!!.getUserAndPetDistance()
+ } else if (null != mHomeMapGoogleMapFragment) {
+ distance = mHomeMapGoogleMapFragment!!.getUserAndPetDistance()
+ }
+ return distance
+ }
+
+ /**
+ * 开始水波纹动画
+ */
+ fun startRippleCircleAnim() {
+ if (null != mHomeMapBaiduMapFragment) {
+ } else if (null != mHomeMapGoogleMapFragment) {
+ mHomeMapGoogleMapFragment!!.startRippleCircleAnim()
+ }
+ }
+
+ fun greenRippleCircleAnim() {
+ mHomeMapGoogleMapFragment?.greenRippleCircleAnim()
+ }
+
+ fun setMarkerInfoViewOffset() {
+ if (null != mHomeMapBaiduMapFragment) {
+ } else if (null != mHomeMapGoogleMapFragment) {
+ mHomeMapGoogleMapFragment!!.setMarkerInfoViewOffset()
+ }
+ }
+
+// fun getAddressShowMarkerInfoWindow(historyDataBean: HistoryDataBean) {
+// if (null != mHomeMapBaiduMapFragment) {
+// mHomeMapBaiduMapFragment!!.showMarkerInfoWindow(historyDataBean)
+// } else if (null != mHomeMapGoogleMapFragment) {
+// mHomeMapGoogleMapFragment!!.showMarkerInfoWindow(historyDataBean)
+// }
+// }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/MapV3Fragment.kt b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/MapV3Fragment.kt
index 53205ba..e47aceb 100644
--- a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/MapV3Fragment.kt
+++ b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/MapV3Fragment.kt
@@ -18,8 +18,8 @@ import com.abbidot.baselibrary.list.BaseRecyclerAdapter
import com.abbidot.baselibrary.util.AppUtils
import com.abbidot.baselibrary.util.LogUtil
import com.abbidot.baselibrary.util.MMKVUtil
+import com.abbidot.baselibrary.util.Utils
import com.abbidot.tracker.R
-import com.abbidot.tracker.adapter.HomeMapDeviceMsgAdapter
import com.abbidot.tracker.adapter.HomeMapDeviceStateAdapter
import com.abbidot.tracker.base.BaseDialog
import com.abbidot.tracker.base.BaseFragment
@@ -37,15 +37,14 @@ import com.abbidot.tracker.dialog.CommonDialog1
import com.abbidot.tracker.dialog.SelectMapTypeDialog
import com.abbidot.tracker.ui.activity.HomeV2Activity
import com.abbidot.tracker.ui.activity.device.MyTrackerV2Activity
-import com.abbidot.tracker.ui.activity.map.LiveActivityV2
-import com.abbidot.tracker.ui.common.map.HomeMapCommon
+import com.abbidot.tracker.ui.activity.map.LiveActivityV3
+import com.abbidot.tracker.ui.common.map.HomeMapCommonV3
import com.abbidot.tracker.util.Util
import com.abbidot.tracker.util.ViewUtil
import com.abbidot.tracker.util.bluetooth.SRBleUtil
import com.abbidot.tracker.vm.FamilyViewModel
import com.abbidot.tracker.vm.FencesMapViewModel
import com.abbidot.tracker.vm.MapViewModel
-import com.abbidot.tracker.widget.MapDeviceNetView
import com.clj.fastble.BleManager
import com.hjq.permissions.XXPermissions
import com.hjq.permissions.permission.PermissionLists
@@ -74,14 +73,14 @@ class MapV3Fragment : BaseFragment(FragmentMapV3Binding::i
private var mCurrentShowPetPos = -1
@Inject
- lateinit var mHomeMapCommon: HomeMapCommon
+ lateinit var mHomeMapCommon: HomeMapCommonV3
private lateinit var mFragment: Fragment
private var mMapDeviceBean: MapDeviceBean? = null
private lateinit var mDeviceStateList: MutableList
private lateinit var mDeviceStateAdapter: HomeMapDeviceStateAdapter
- private lateinit var mDeviceMsgList: MutableList
- private lateinit var mDeviceMsgAdapter: HomeMapDeviceMsgAdapter
+// private lateinit var mDeviceMsgList: MutableList
+// private lateinit var mDeviceMsgAdapter: HomeMapDeviceMsgAdapter
//启动移动地图摄像机
private var isMoveCamera = true
@@ -113,7 +112,10 @@ class MapV3Fragment : BaseFragment(FragmentMapV3Binding::i
rlHomeMapTopLayout, WindowInsetsCompat.Type.statusBars()
)
mFragment = mHomeMapCommon.getMapFragment(
- mContext!!, miHomeMapAddressView, MapDeviceNetView(mContext!!)
+ mContext!!,
+ ilHomeMapPetLocation,
+ llHomeMapDeviceBatteryLayout,
+ Utils.DATE_FORMAT_PATTERN_EN11
) { mapLoadOk() }
llHomeMapTopPet.ivTopPetBtnSmall.setImageResource(R.drawable.icon_map_type)
@@ -123,17 +125,16 @@ class MapV3Fragment : BaseFragment(FragmentMapV3Binding::i
)
mDeviceStateList = mutableListOf()
- mDeviceMsgList = mutableListOf()
mMapViewModel.addDeviceDefaultStateData(mContext!!, mDeviceStateList)
mDeviceStateAdapter = HomeMapDeviceStateAdapter(mContext!!, mDeviceStateList)
ViewUtil.instance.setRecyclerViewVerticalLinearLayout(
mContext!!, rvHomeMapDeviceState, mDeviceStateAdapter, bottom = 10
)
- mDeviceMsgAdapter = HomeMapDeviceMsgAdapter(mContext!!, mDeviceMsgList)
- ViewUtil.instance.setRecyclerViewVerticalLinearLayout(
- mContext!!, rvHomeMapDeviceMsg, mDeviceMsgAdapter, bottom = 10
- )
+// mDeviceMsgAdapter = HomeMapDeviceMsgAdapter(mContext!!, mDeviceMsgList)
+// ViewUtil.instance.setRecyclerViewVerticalLinearLayout(
+// mContext!!, rvHomeMapDeviceMsg, mDeviceMsgAdapter, bottom = 10
+// )
setOnClickListenerViews(
homeMapRefreshBtn,
@@ -141,7 +142,9 @@ class MapV3Fragment : BaseFragment(FragmentMapV3Binding::i
homeMapLiveBtn,
llHomeMapTopPet.ivTopPetBtnSmall,
llHomeMapTopPet.homeDataPetNameSmall,
- llHomeMapTopPet.homeDataPetHeadSmall.root
+ llHomeMapTopPet.homeDataPetHeadSmall.root,
+ ilHomeMapDeviceBatteryLayout.ivDeviceCloseBtn,
+ ilHomeMapDeviceMsg.ivDeviceMsgCloseBtn
)
if (AppUtils.isDebug()) {
@@ -230,17 +233,22 @@ class MapV3Fragment : BaseFragment(FragmentMapV3Binding::i
override fun onResult(any: Any) {
val data = it.getOrNull()
data?.apply {
+ mMapDeviceBean?.let { m ->
+ data.isCloseMsg = m.isCloseMsg
+ data.isCloseBattery = m.isCloseBattery
+ data.canShowBattery = m.canShowBattery
+ }
mMapDeviceBean = data
setMapData(data)
mMapViewModel.setDeviceStateAndWarningData(
mContext!!,
getHomeV2Activity()?.getPet(),
data,
+ mViewBinding.ilHomeMapDeviceMsg.root,
+ mViewBinding.ilHomeMapDeviceMsg.tvDeviceMsgContent,
+ mViewBinding.ilHomeMapDeviceMsg.ivDeviceMsgCloseBtn,
mDeviceStateList,
- mDeviceStateAdapter,
- mDeviceMsgList,
- mDeviceMsgAdapter,
- mViewBinding.rvHomeMapDeviceMsg
+ mDeviceStateAdapter
)
}
}
@@ -288,11 +296,26 @@ class MapV3Fragment : BaseFragment(FragmentMapV3Binding::i
//接收蓝牙连接状态
XEventBus.observe(this, EventName.ConnectDeviceState) { trackBle: BleTrackDeviceBean ->
getHomeV2Activity()?.getPet(false)?.apply {
- //蓝牙断开就重新获取服务器数据,蓝牙数据上报断开
- if (trackBle.mac == macID && trackBle.conState != ConState.CONNECTED) {
- //隐藏蓝牙nearby
- mViewBinding.rvHomeMapDeviceMsg.visibility = View.GONE
- updateMapDeviceStatus()
+ if (trackBle.mac == macID) {
+ if (trackBle.conState == ConState.CONNECTED) {
+ mMapDeviceBean?.let {
+ mMapViewModel.setDeviceStateAndWarningData(
+ mContext!!,
+ getHomeV2Activity()?.getPet(),
+ it,
+ mViewBinding.ilHomeMapDeviceMsg.root,
+ mViewBinding.ilHomeMapDeviceMsg.tvDeviceMsgContent,
+ mViewBinding.ilHomeMapDeviceMsg.ivDeviceMsgCloseBtn,
+ mDeviceStateList,
+ mDeviceStateAdapter
+ )
+ }
+ } else {
+ //隐藏蓝牙nearby
+ mViewBinding.ilHomeMapDeviceMsg.root.visibility = View.GONE
+ //蓝牙断开就重新获取服务器数据,蓝牙数据上报断开
+ updateMapDeviceStatus()
+ }
}
}
}
@@ -314,26 +337,24 @@ class MapV3Fragment : BaseFragment(FragmentMapV3Binding::i
it.longitude = location.longitude
it.latitude = location.latitude
}
- mHomeMapCommon.setMapDeviceBean(mMapDeviceBean)
+ setMapDeviceBean(it)
mHomeMapCommon.refreshPetCurrentLocation(
it.latitude, it.longitude, isMoveCamera
)
mHomeMapCommon.startRefreshUserLocation()
}
+ ViewUtil.instance.viewShow(mViewBinding.homeMapLiveBtn)
+ mMapViewModel.setDeviceStateAndWarningData(
+ mContext!!,
+ getHomeV2Activity()?.getPet(),
+ it,
+ mViewBinding.ilHomeMapDeviceMsg.root,
+ mViewBinding.ilHomeMapDeviceMsg.tvDeviceMsgContent,
+ mViewBinding.ilHomeMapDeviceMsg.ivDeviceMsgCloseBtn,
+ mDeviceStateList,
+ mDeviceStateAdapter
+ )
}
-
- mViewBinding.homeMapLiveBtn.visibility = View.VISIBLE
-
- mMapViewModel.setDeviceStateAndWarningData(
- mContext!!,
- getHomeV2Activity()?.getPet(),
- mMapDeviceBean!!,
- mDeviceStateList,
- mDeviceStateAdapter,
- mDeviceMsgList,
- mDeviceMsgAdapter,
- mViewBinding.rvHomeMapDeviceMsg
- )
}
}
}
@@ -438,10 +459,6 @@ class MapV3Fragment : BaseFragment(FragmentMapV3Binding::i
private fun updateMapDeviceStatus(
isNeedCountDown: Boolean = true, useBleLocation: Boolean = false
) {
-// mShowCenterLocationType = ConstantInt.PetLocationType
-// ViewUtil.instance.setMapSwitchLocationButtonImage(
-// mViewBinding.homeMapRefreshBtn, mShowCenterLocationType
-// )
getHomeV2Activity()?.apply {
if (mPetList.size <= mCurrentShowPetPos) return
getPet()?.apply {
@@ -531,8 +548,12 @@ class MapV3Fragment : BaseFragment(FragmentMapV3Binding::i
if (mHomeMapCommon.isMapLoadOk()) {
isMoveCamera = true
mHomeMapCommon.clearMarker()
- mViewBinding.miHomeMapAddressView.visibility = View.GONE
- mViewBinding.rvHomeMapDeviceMsg.visibility = View.GONE
+ mMapDeviceBean?.let {
+ it.isCloseMsg = false
+ it.isCloseBattery = false
+ it.canShowBattery = false
+ }
+ mViewBinding.ilHomeMapDeviceMsg.root.visibility = View.GONE
showLoading(true)
val pet = mPetList[position]
//重新设置地图宠物头像
@@ -555,7 +576,7 @@ class MapV3Fragment : BaseFragment(FragmentMapV3Binding::i
if (Util.isTimeoutReport(updateTime) || powerSwitch == ConstantInt.Type0 || powerSwitch == ConstantInt.Type2 || inWifiZone == ConstantInt.Type1) View.GONE
else View.VISIBLE
- mHomeMapCommon.setMapDeviceBean(this)
+ setMapDeviceBean(this)
//设置循环查询时间间隔 30秒
mMapViewModel.updateMillisInFuture(0.5f)
@@ -565,10 +586,6 @@ class MapV3Fragment : BaseFragment(FragmentMapV3Binding::i
}
}
-// mShowCenterLocationType = ConstantInt.PetLocationType
-// ViewUtil.instance.setMapSwitchLocationButtonImage(
-// mViewBinding.homeMapRefreshBtn, mShowCenterLocationType
-// )
mHomeMapCommon.refreshPetCurrentLocation(latitude, longitude, isMoveCamera)
mHomeMapCommon.startRefreshUserLocation()
@@ -576,6 +593,22 @@ class MapV3Fragment : BaseFragment(FragmentMapV3Binding::i
}
}
+ private fun setMapDeviceBean(mapDeviceBean: MapDeviceBean) {
+ mapDeviceBean.apply {
+ mViewBinding.ilHomeMapDeviceBatteryLayout.let {
+ mMapViewModel.setMapDeviceBattery(
+ mContext!!, mapDeviceBean, it.root, it.tvDeviceBatteryInfo, it.ivDeviceCloseBtn
+ )
+ }
+ mViewBinding.ilHomeMapPetLocation.let {
+ mMapViewModel.setPetLocationReverseGeocode(
+ mContext!!, mapDeviceBean, it.root, it.tvPetLocationReverseGeocode
+ )
+ }
+ mHomeMapCommon.setMapDeviceBean(this)
+ }
+ }
+
/**
* 检查获取定位,蓝牙权限
*/
@@ -591,7 +624,7 @@ class MapV3Fragment : BaseFragment(FragmentMapV3Binding::i
} else {
getPet()?.apply {
mViewBinding.homeMapLiveBtn.isEnabled = false
- val intent = Intent(mContext, LiveActivityV2::class.java)
+ val intent = Intent(mContext, LiveActivityV3::class.java)
intent.putExtra(ConstantString.JumpActivity, true)
intent.putExtra(ConstantString.Pet, this)
startActivity(intent)
@@ -605,7 +638,7 @@ class MapV3Fragment : BaseFragment(FragmentMapV3Binding::i
} else {
getPet()?.apply {
mViewBinding.homeMapBluetoothBtn.isEnabled = false
- val intent = Intent(mContext, LiveActivityV2::class.java)
+ val intent = Intent(mContext, LiveActivityV3::class.java)
intent.putExtra(ConstantString.JumpActivity, false)
intent.putExtra(ConstantString.Pet, this)
startActivity(intent)
@@ -644,7 +677,7 @@ class MapV3Fragment : BaseFragment(FragmentMapV3Binding::i
getHomeV2Activity()?.let {
it.getPet()?.apply {
mViewBinding.homeMapLiveBtn.isEnabled = false
- val intent = Intent(mContext, LiveActivityV2::class.java)
+ val intent = Intent(mContext, LiveActivityV3::class.java)
intent.putExtra(ConstantString.JumpActivity, true)
intent.putExtra(ConstantString.Pet, this)
startActivity(intent)
@@ -655,6 +688,15 @@ class MapV3Fragment : BaseFragment(FragmentMapV3Binding::i
llHomeMapTopPet.ivTopPetBtnSmall -> showMapTypeDialog()
homeMapBluetoothBtn -> checkPermissions(1)
llHomeMapTopPet.homeDataPetNameSmall, llHomeMapTopPet.homeDataPetHeadSmall.root -> getHomeV2Activity()?.selectPetDialog()
+ ilHomeMapDeviceBatteryLayout.ivDeviceCloseBtn -> {
+ mMapDeviceBean?.isCloseBattery = true
+ llHomeMapDeviceBatteryLayout.visibility = View.INVISIBLE
+ }
+
+ ilHomeMapDeviceMsg.ivDeviceMsgCloseBtn -> {
+ mMapDeviceBean?.isCloseMsg = true
+ ilHomeMapDeviceMsg.root.visibility = View.GONE
+ }
}
}
diff --git a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/BaseGoogleMapFragment.kt b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/BaseGoogleMapFragment.kt
index c4d5889..c27aa11 100644
--- a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/BaseGoogleMapFragment.kt
+++ b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/BaseGoogleMapFragment.kt
@@ -21,6 +21,7 @@ import com.abbidot.tracker.R
import com.abbidot.tracker.base.BaseFragment
import com.abbidot.tracker.bean.FencesBean
import com.abbidot.tracker.bean.HistoryDataBean
+import com.abbidot.tracker.bean.MapDeviceBean
import com.abbidot.tracker.constant.ConstantInt
import com.abbidot.tracker.databinding.FragmentGoogleMapBinding
import com.abbidot.tracker.util.ImageUtil
@@ -392,13 +393,16 @@ abstract class BaseGoogleMapFragment :
}
//刷新当前位置ok,延时等待移动地图摄像头动画
- if (isAnimMoveCamera) {
- mGoogleMapView.postDelayed({
- onRefreshPetCurrentLocationOk(mGoogleMap!!)
- }, 1000)
- } else {
+// if (isAnimMoveCamera) {
+// mGoogleMapView.postDelayed({
+// onRefreshPetCurrentLocationOk(mGoogleMap!!)
+// }, 1000)
+// } else {
+// onRefreshPetCurrentLocationOk(mGoogleMap!!)
+// }
+ mGoogleMapView.postDelayed({
onRefreshPetCurrentLocationOk(mGoogleMap!!)
- }
+ }, 500)
}
}
}
@@ -1066,6 +1070,21 @@ abstract class BaseGoogleMapFragment :
}
}
+ /**
+ * 设置Marker弹窗设备电量的位置
+ */
+ fun setMapDeviceBatteryOffset(
+ viewGroup: ViewGroup, latLng: LatLng, mapDeviceBean: MapDeviceBean
+ ) {
+ mGoogleMap?.projection?.toScreenLocation(latLng)?.let {
+ viewGroup.x = it.x.toFloat() - viewGroup.width / 2 + AppUtils.dpToPx(5)
+ viewGroup.y = it.y.toFloat() - AppUtils.dpToPx(56) - viewGroup.height
+ if (mapDeviceBean.canShowBattery && !mapDeviceBean.isCloseBattery) ViewUtil.instance.viewShow(
+ viewGroup
+ )
+ }
+ }
+
/**
* 设置地图网络类型显示位置
*/
diff --git a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/HomeMapGoogleMapFragmentV3.kt b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/HomeMapGoogleMapFragmentV3.kt
new file mode 100644
index 0000000..6e939a1
--- /dev/null
+++ b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/HomeMapGoogleMapFragmentV3.kt
@@ -0,0 +1,320 @@
+package com.abbidot.tracker.ui.fragment.map.googlemap
+
+import android.animation.ValueAnimator
+import android.content.Context
+import android.view.View
+import android.view.ViewGroup
+import android.view.animation.LinearInterpolator
+import androidx.core.content.ContextCompat
+import androidx.core.view.isGone
+import androidx.fragment.app.viewModels
+import com.abbidot.baselibrary.util.AppUtils
+import com.abbidot.baselibrary.util.Utils
+import com.abbidot.tracker.R
+import com.abbidot.tracker.bean.HistoryDataBean
+import com.abbidot.tracker.bean.MapDeviceBean
+import com.abbidot.tracker.databinding.LayoutPetLocationInfoBinding
+import com.abbidot.tracker.util.Util
+import com.abbidot.tracker.util.ViewUtil
+import com.abbidot.tracker.vm.GeoCoderViewModel
+import com.google.android.gms.maps.GoogleMap
+import com.google.android.gms.maps.model.Circle
+import com.google.android.gms.maps.model.CircleOptions
+import com.google.android.gms.maps.model.LatLng
+import com.google.android.gms.maps.model.Marker
+import com.google.android.gms.maps.model.Polyline
+import com.google.android.gms.maps.model.PolylineOptions
+import kotlin.math.pow
+
+/**
+ *Created by .yzq on 2022/1/13/013.
+ * @link
+ * @description:首页map谷歌地图
+ */
+class HomeMapGoogleMapFragmentV3 : BaseGoogleMapFragment() {
+
+ private val mGeoCoderViewModel: GeoCoderViewModel by viewModels()
+
+ private lateinit var mPetLocationLayoutBinding: LayoutPetLocationInfoBinding
+ private lateinit var mDeviceBatteryLayout: ViewGroup
+
+ //宠物当前反地理位置信息
+ var mDecPetAddressData: HistoryDataBean? = null
+ private var mMapDeviceBean: MapDeviceBean? = null
+ private lateinit var mMapLoadOk: () -> Unit
+
+ //启动动画移动地图摄像机
+ private var isMoveCamera = true
+ private var mPolyline: Polyline? = null
+ private var mRippleCircle: Circle? = null
+ private var mValueAnimator: ValueAnimator? = null
+
+ private var mRippleCirclePercent = 0.0
+ private var mRippleCircleRadius = 200
+ private var isMapCameraMove = false
+ private var mPetAddressTimeFormat = Utils.DATE_FORMAT_PATTERN_EN11
+
+ companion object {
+ @JvmStatic
+ fun newInstance(
+ context: Context,
+ locationLayoutViewBinding: LayoutPetLocationInfoBinding,
+ deviceBatteryLayout: ViewGroup,
+ petAddressTimeFormat: String,
+ mapLoadOk: () -> Unit
+ ) = HomeMapGoogleMapFragmentV3().apply {
+ mContext = context
+ mDeviceBatteryLayout = deviceBatteryLayout
+ mPetLocationLayoutBinding = locationLayoutViewBinding
+ mPetAddressTimeFormat = petAddressTimeFormat
+ mMapLoadOk = mapLoadOk
+ }
+ }
+
+ fun setMapDeviceBean(mapDeviceBean: MapDeviceBean?) {
+ mMapDeviceBean = mapDeviceBean
+ }
+
+ override fun liveDataObserve() {
+ //反地理编码成功返回
+ mGeoCoderViewModel.mLatLonAddressLiveData.observe(viewLifecycleOwner) {
+ //保存地理信息,方便传参给导航页面
+ if (null == mDecPetAddressData) mDecPetAddressData = HistoryDataBean()
+
+ mMapDeviceBean?.apply {
+ val timeString = Utils.formatTime(latLonUpdateTime * 1000, mPetAddressTimeFormat)
+ mDecPetAddressData?.let { history ->
+ //更新位置时间
+ history.dayTime = timeString
+ //详细位置
+ history.address = it
+ //传递位置信息给InfoWindowAdapter窗口
+// mMarker?.tag = history
+
+// showMarkerInfoWindow(history)
+ val address = String.format(mContext!!.getString(R.string.txt_near), it)
+ ViewUtil.instance.viewShow(mPetLocationLayoutBinding.root)
+ mPetLocationLayoutBinding.let { layout ->
+ layout.tvPetLocationReverseGeocode.text = address
+ layout.tvPetLocationUpdateTime.text = timeString
+ }
+ }
+ }
+ }
+ }
+
+ override fun onMapLoadOk(googleMap: GoogleMap) {
+ //设置自定义头部地点布局
+ mGoogleMap?.apply {
+ setOnCameraIdleListener {
+ if (isMapCameraMove) {
+ isMapCameraMove = false
+ } else {
+ setMarkerInfoViewOffset()
+ }
+ }
+ setOnCameraMoveListener {
+ isMapCameraMove = true
+ setMarkerInfoViewOffset()
+ }
+
+ setOnMarkerClickListener(object : GoogleMap.OnMarkerClickListener {
+ override fun onMarkerClick(marker: Marker): Boolean {
+ if (marker == mMarker) {
+ mMapDeviceBean?.let {
+ if (it.canShowBattery) {
+ mDeviceBatteryLayout.visibility = if (mDeviceBatteryLayout.isGone) {
+ it.isCloseBattery = false
+ View.VISIBLE
+ } else {
+ it.isCloseBattery = true
+ View.GONE
+ }
+ }
+ }
+ return true
+ }
+ return false
+ }
+ })
+ getLastLocation()
+ }
+
+ //变量是否初始化
+ if (::mMapLoadOk.isInitialized) mMapLoadOk()
+ }
+
+ override fun onRefreshPetCurrentLocationOk(googleMap: GoogleMap) {
+ if (null == mMarker) return
+ else startReverseGeocode()
+ }
+
+ /**
+ * 刚开始的反编译地理位置
+ */
+ private fun startReverseGeocode() {
+ mMapDeviceBean?.apply {
+ mGeoCoderViewModel.getLatLonAddress(latitude, longitude, false)
+ setMarkerInfoViewOffset()
+ }
+ }
+
+ fun setMarkerInfoViewOffset() {
+ mPetLatLng?.apply {
+ mMapDeviceBean?.let {
+ setMapDeviceBatteryOffset(
+ mDeviceBatteryLayout, LatLng(latitude, longitude), it
+ )
+ }
+ }
+ }
+
+ /**
+ * 计算用户和宠物的距离
+ */
+ fun getUserAndPetDistance(): Double {
+ var distance = 0.0
+ mUserLatLng?.apply {
+ mPetLatLng?.let {
+ distance =
+ Util.measureLatLonDistance(latitude, longitude, it.latitude, it.longitude)
+ }
+ }
+ return distance
+ }
+
+ /**
+ * 画用户和宠物之间的虚线
+ */
+ private fun addUserAndPetLine(petLatLng: LatLng) {
+ mUserLatLng?.apply {
+ mGoogleMap?.let {
+ if (null == mPolyline) {
+ val polylineOptions =
+ PolylineOptions().clickable(false).width(AppUtils.dpToPx(1.5f))
+ .color(ContextCompat.getColor(mContext!!, R.color.blue_color9))
+ .geodesic(false)
+ mPolyline = it.addPolyline(polylineOptions)
+ mPolyline?.pattern = getDashedPatternStyle(18f)
+ }
+ mPolyline?.let { pLine ->
+ val latList = mutableListOf()
+ latList.add(petLatLng)
+ latList.add(this)
+ pLine.points = latList
+ }
+ }
+ }
+ }
+
+ /**
+ * 初始化并添加水波纹圆
+ */
+ private fun addRippleCircle() {
+ mPetLatLng?.apply {
+ mGoogleMap?.let {
+ if (null == mRippleCircle) {
+ mRippleCircle = it.addCircle(
+ CircleOptions().center(this)
+ .radius(mRippleCircleRadius * mRippleCirclePercent)
+ .strokeWidth(AppUtils.dpToPx(2).toFloat())
+ .fillColor(ContextCompat.getColor(mContext!!, R.color.black10))
+ .strokeColor(ContextCompat.getColor(mContext!!, R.color.black10))
+ )
+
+ setRippleCircleAnim()
+ }
+ }
+ }
+ }
+
+ /**
+ * 设置水波纹动画
+ */
+ private fun setRippleCircleAnim() {
+ if (null == mValueAnimator) {
+ mValueAnimator = ViewUtil.instance.setValueAnimator(
+ 0.0, 100.0, 1500, LinearInterpolator()
+ ) {
+ mRippleCirclePercent = it.animatedValue as Float / 100.0
+ mRippleCircle?.apply {
+ mPetLatLng?.let { petLatLng ->
+ center = petLatLng
+ radius = mRippleCircleRadius * mRippleCirclePercent
+ }
+ }
+ }?.apply {
+ repeatMode = ValueAnimator.RESTART
+ repeatCount = ValueAnimator.INFINITE
+ }
+ }
+ }
+
+ /**
+ * 画线
+ */
+ fun addLine(latLng: LatLng) {
+// addPolyline(mGoogleMap!!, latLng)
+// addUserAndPetLine(latLng)
+ refreshPetCurrentLocation(latLng, needMoveCamera = isMoveCamera)
+
+// mRippleCircle?.apply {
+// //一像素对应几米
+// val pxDis = 2.0.pow(15.5 - getGoogleMapZoom())
+// mRippleCircleRadius = (pxDis * 150).toInt()
+// fillColor = (ContextCompat.getColor(mContext!!, R.color.select_color5))
+// strokeColor = (ContextCompat.getColor(mContext!!, R.color.select_color5))
+// mValueAnimator?.duration = 2000
+// }
+ }
+
+ /**
+ * 画多条线
+ */
+ fun addLines(trackList: MutableList) {
+ val latLngList = mutableListOf()
+ for (i in 0 until trackList.size) {
+ trackList[i].apply {
+ val latLng = LatLng(latitude, longitude)
+ latLngList.add(latLng)
+ if (i == trackList.size - 1) {
+// addUserAndPetLine(latLng)
+ refreshPetCurrentLocation(latLng, needMoveCamera = isMoveCamera)
+ }
+ }
+ }
+// addPolyLines(mGoogleMap!!, latLngList)
+ }
+
+ /**
+ * 开始水波纹动画
+ */
+ fun startRippleCircleAnim() {
+ mPetLatLng?.apply {
+ //一像素对应几米
+ val pxDis = 2.0.pow(15.5 - getGoogleMapZoom())
+ mRippleCircleRadius = (pxDis * 150).toInt()
+// addUserAndPetLine(this)
+ addRippleCircle()
+ }
+ }
+
+ /**
+ * 直播开始之后,改变绿色波纹动画
+ */
+ fun greenRippleCircleAnim() {
+ mRippleCircle?.apply {
+ //一像素对应几米
+ val pxDis = 2.0.pow(15.5 - getGoogleMapZoom())
+ mRippleCircleRadius = (pxDis * 150).toInt()
+ fillColor = (ContextCompat.getColor(mContext!!, R.color.select_color5))
+ strokeColor = (ContextCompat.getColor(mContext!!, R.color.select_color5))
+ mValueAnimator?.duration = 2000
+ }
+ }
+
+ override fun onDetach() {
+ super.onDetach()
+ mValueAnimator?.cancel()
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/abbidot/tracker/util/ViewUtil.kt b/app/src/main/java/com/abbidot/tracker/util/ViewUtil.kt
index 8de9828..1b253a3 100644
--- a/app/src/main/java/com/abbidot/tracker/util/ViewUtil.kt
+++ b/app/src/main/java/com/abbidot/tracker/util/ViewUtil.kt
@@ -36,6 +36,7 @@ import android.widget.TextView
import androidx.annotation.DrawableRes
import androidx.core.content.ContextCompat
import androidx.core.view.isGone
+import androidx.core.view.isInvisible
import androidx.core.view.setPadding
import androidx.core.widget.addTextChangedListener
import androidx.fragment.app.FragmentActivity
@@ -1116,6 +1117,6 @@ class ViewUtil private constructor() {
}
fun viewShow(view: View) {
- if (view.isGone) view.visibility = View.VISIBLE
+ if (view.isGone || view.isInvisible) view.visibility = View.VISIBLE
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/abbidot/tracker/vm/MapViewModel.kt b/app/src/main/java/com/abbidot/tracker/vm/MapViewModel.kt
index 2a831a8..c1b25c2 100644
--- a/app/src/main/java/com/abbidot/tracker/vm/MapViewModel.kt
+++ b/app/src/main/java/com/abbidot/tracker/vm/MapViewModel.kt
@@ -2,6 +2,10 @@ package com.abbidot.tracker.vm
import android.content.Context
import android.os.CountDownTimer
+import android.view.View
+import android.view.ViewGroup
+import androidx.appcompat.widget.AppCompatImageView
+import androidx.core.content.ContextCompat
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
@@ -17,6 +21,8 @@ import com.abbidot.tracker.retrofit2.NetworkApi
import com.abbidot.tracker.util.Util
import com.abbidot.tracker.util.ViewUtil
import com.abbidot.tracker.util.bluetooth.SRBleUtil
+import com.abbidot.tracker.widget.TypefaceButton
+import com.abbidot.tracker.widget.TypefaceTextView
import kotlinx.coroutines.launch
class MapViewModel : ViewModel() {
@@ -28,8 +34,7 @@ class MapViewModel : ViewModel() {
private var mRefreshDataMin = 0.5f
private var mDeviceId = ""
- //警告动画是否结束
- private var isWarningAnimEnd = true
+ private var mDeviceMsgType = ConstantInt.SpecialType
fun getMapDeviceStatus(deviceId: String, isNeedCountDown: Boolean = true) {
viewModelScope.launch {
@@ -199,6 +204,63 @@ class MapViewModel : ViewModel() {
}
}
+ /**
+ * 设置设备状态和告警信息显示
+ */
+ fun setDeviceStateAndWarningData(
+ context: Context,
+ petBean: PetBean?,
+ mapDeviceBean: MapDeviceBean,
+ rootView: ViewGroup,
+ tvDeviceMsgView: TypefaceButton,
+ deviceMsgCloseBtn: AppCompatImageView,
+ deviceStateList: MutableList,
+ deviceStateAdapter: BaseRecyclerAdapter,
+ ) {
+ mapDeviceBean.apply {
+ tvDeviceMsgView.setBackgroundResource(R.color.device_msg_color1)
+ if (null != petBean && null != SRBleUtil.instance.getConnectMacDevice(petBean.macID)) {
+ if (isCloseMsg && mDeviceMsgType == ConstantInt.Type0) {
+
+ } else {
+ val nearby =
+ String.format(context.getString(R.string.txt_is_nearby), petBean.petName)
+ tvDeviceMsgView.text = nearby
+ isCloseMsg = false
+ tvDeviceMsgView.setBackgroundResource(R.color.green_color10)
+ ViewUtil.instance.viewShow(rootView)
+ deviceMsgCloseBtn.visibility = View.GONE
+ }
+ } else if (inNoGoZone == ConstantInt.BadZone) {
+ if (isCloseMsg && mDeviceMsgType == ConstantInt.Type1) {
+
+ } else {
+ tvDeviceMsgView.text = context.getString(R.string.txt_in_no_go_zone)
+ ViewUtil.instance.viewShow(deviceMsgCloseBtn)
+ ViewUtil.instance.viewShow(rootView)
+ isCloseMsg = false
+ mDeviceMsgType = ConstantInt.Type1
+ }
+ } else if (inSafeZone == ConstantInt.BadZone) {
+ if (isCloseMsg && mDeviceMsgType == ConstantInt.Type2) {
+
+ } else {
+ tvDeviceMsgView.text = context.getString(R.string.txt_out_save_zone)
+ ViewUtil.instance.viewShow(rootView)
+ ViewUtil.instance.viewShow(deviceMsgCloseBtn)
+ isCloseMsg = false
+ mDeviceMsgType = ConstantInt.Type2
+ }
+ } else {
+ mDeviceMsgType = ConstantInt.Type3
+ rootView.visibility = View.GONE
+ }
+ setDeviceState(context, mapDeviceBean, deviceStateList)
+
+ deviceStateAdapter.notifyItemRangeChanged(0, deviceStateList.size)
+ }
+ }
+
/**
* 设置没有的状态
*/
@@ -363,6 +425,71 @@ class MapViewModel : ViewModel() {
}
}
+ fun setMapDeviceBattery(
+ context: Context,
+ mapDeviceBean: MapDeviceBean,
+ rootView: ViewGroup,
+ batteryText: TypefaceTextView,
+ closeBtn: AppCompatImageView
+ ) {
+ mapDeviceBean.apply {
+ if (isCloseBattery) return@apply
+ batteryText.let {
+ canShowBattery = true
+ rootView.visibility = View.VISIBLE
+ if (powerSwitch == ConstantInt.Type0) {
+ it.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0)
+ it.text = context.getString(R.string.txt_powered_off)
+ ViewUtil.instance.viewShow(closeBtn)
+ } else if (powerSwitch == ConstantInt.Type3) {
+ it.setCompoundDrawablesWithIntrinsicBounds(
+ R.drawable.icon_charge_image, 0, 0, 0
+ )
+ it.text = context.getString(R.string.txt_charging)
+ ViewUtil.instance.viewShow(closeBtn)
+ } else if (batteryLevel <= ConstantInt.LowBattery30) {
+ val lowBattery =
+ if (batteryLevel <= ConstantInt.LowBattery10) ConstantInt.LowBattery10
+ else if (batteryLevel <= ConstantInt.LowBattery20) ConstantInt.LowBattery20
+ else ConstantInt.LowBattery30
+ it.setCompoundDrawablesWithIntrinsicBounds(
+ R.drawable.icon_low_battery_image, 0, 0, 0
+ )
+ it.text = String.format(
+ context.getString(R.string.txt_battery_less_than), "$lowBattery"
+ )
+ } else {
+ rootView.visibility = View.INVISIBLE
+ canShowBattery = false
+ }
+ }
+ }
+ }
+
+
+ fun setPetLocationReverseGeocode(
+ context: Context,
+ mapDeviceBean: MapDeviceBean,
+ rootView: ViewGroup,
+ locationText: TypefaceTextView,
+ ) {
+ mapDeviceBean.apply {
+ val imageResId = if (inWifiZone == ConstantInt.Type1) {
+ rootView.background =
+ ContextCompat.getDrawable(context, R.drawable.shape16_light_green_color_bg)
+ R.drawable.icon_wifi_image
+ } else {
+ rootView.background =
+ ContextCompat.getDrawable(context, R.drawable.shape16_white_color_bg)
+ R.drawable.icon_wifi_image
+ 0
+ }
+ locationText.setCompoundDrawablesWithIntrinsicBounds(
+ imageResId, 0, 0, 0
+ )
+ }
+ }
+
/**
* 停止获取数据
*/
diff --git a/app/src/main/java/com/abbidot/tracker/widget/MapBatteryView.kt b/app/src/main/java/com/abbidot/tracker/widget/MapBatteryView.kt
deleted file mode 100644
index 38fb2ac..0000000
--- a/app/src/main/java/com/abbidot/tracker/widget/MapBatteryView.kt
+++ /dev/null
@@ -1,133 +0,0 @@
-package com.abbidot.tracker.widget
-
-import android.content.Context
-import android.graphics.Canvas
-import android.graphics.Paint
-import android.graphics.Path
-import android.text.TextUtils
-import android.util.AttributeSet
-import android.view.View
-import androidx.core.content.ContextCompat
-import com.abbidot.baselibrary.util.AppUtils
-import com.abbidot.tracker.R
-import com.qmuiteam.qmui.util.QMUIDisplayHelper
-
-/**
- *Created by .yzq on 2024/8/26/026.
- * @link
- * @description:
- */
-class MapBatteryView : View {
-
- private lateinit var mContext: Context
- private var mOffsetX = 0
- private var mOffsetY = 0
-
- //文字和边界的距离。三角形的直线长
- private var mPadding = 0
-
- private lateinit var mTextPaint: Paint
- private lateinit var mPaint: Paint
-
- //小三角形的path
- private lateinit var mTrianglePath: Path
-
- private var mTimeText = ""
- private var mAddressText = ""
-
- constructor(context: Context) : super(context) {
- init(context)
- }
-
- constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
- context, attrs, defStyleAttr
- ) {
- init(context)
- }
-
- constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
- init(context)
- }
-
- private fun init(context: Context) {
- //禁用硬件加速,防止返回到界面多次执行onDraw
- setLayerType(LAYER_TYPE_SOFTWARE, null)
- mContext = context
- mPaint = Paint().apply {
- color = ContextCompat.getColor(mContext, R.color.white)
- }
- //开启抗锯齿
- mTextPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
- color = ContextCompat.getColor(mContext, R.color.black)
- textSize = QMUIDisplayHelper.sp2px(mContext, 12).toFloat()
- }
- mPadding = AppUtils.dpToPx(6)
-
- mTrianglePath = Path()
- }
-
- override fun onDraw(canvas: Canvas) {
- super.onDraw(canvas)
- canvas.apply {
- startDraw(this)
- }
- }
-
- private fun startDraw(canvas: Canvas) {
- if (TextUtils.isEmpty(mAddressText) && TextUtils.isEmpty(mTimeText)) return
- mTrianglePath.apply {
- reset()
- moveTo((mOffsetX - mPadding).toFloat(), (mOffsetY - mPadding).toFloat())
- lineTo(mOffsetX.toFloat(), mOffsetY.toFloat())
- lineTo((mOffsetX + mPadding).toFloat(), (mOffsetY - mPadding).toFloat())
- close()
- }
- canvas.apply {
-
- drawPath(mTrianglePath, mPaint)
-
- val fontMetrics = mTextPaint.fontMetrics
- //文字高度
- val textHeight = fontMetrics.bottom - fontMetrics.top
- //时间文字宽度
- val timeTextWith = mTextPaint.measureText(mTimeText)
- //地址文字宽度
- val addressTextWith = mTextPaint.measureText(mAddressText)
- val maxTextWith = maxOf(timeTextWith, addressTextWith)
-
- drawRoundRect(
- mOffsetX - maxTextWith / 2 - mPadding,
- mOffsetY - textHeight * 2 - mPadding * 2,
- mOffsetX + maxTextWith / 2 + mPadding,
- mOffsetY.toFloat() - mPadding,
- AppUtils.dpToPx(6f),
- AppUtils.dpToPx(6f),
- mPaint
- )
- drawText(
- mTimeText,
- mOffsetX - timeTextWith / 2,
- mOffsetY - textHeight / 2 - mPadding,
- mTextPaint
- )
- drawText(
- mAddressText,
- mOffsetX - addressTextWith / 2,
- mOffsetY - textHeight / 2 - textHeight - mPadding,
- mTextPaint
- )
- }
- }
-
- fun setShowText(time: String, address: String) {
- mTimeText = time
- mAddressText = address
- invalidate()
- }
-
- fun setOffsetXY(x: Int, y: Int) {
- mOffsetX = x
- mOffsetY = y
- invalidate()
- }
-}
\ No newline at end of file
diff --git a/app/src/main/res/drawable-xhdpi/icon_charge_image.png b/app/src/main/res/drawable-xhdpi/icon_charge_image.png
new file mode 100644
index 0000000..180c924
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_charge_image.png differ
diff --git a/app/src/main/res/drawable-xhdpi/icon_low_battery_image.png b/app/src/main/res/drawable-xhdpi/icon_low_battery_image.png
new file mode 100644
index 0000000..d89a6a7
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/icon_low_battery_image.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/icon_charge_image.png b/app/src/main/res/drawable-xxhdpi/icon_charge_image.png
new file mode 100644
index 0000000..ec97750
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_charge_image.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/icon_low_battery_image.png b/app/src/main/res/drawable-xxhdpi/icon_low_battery_image.png
new file mode 100644
index 0000000..d1c94b6
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/icon_low_battery_image.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/icon_charge_image.png b/app/src/main/res/drawable-xxxhdpi/icon_charge_image.png
new file mode 100644
index 0000000..564d77b
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_charge_image.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/icon_low_battery_image.png b/app/src/main/res/drawable-xxxhdpi/icon_low_battery_image.png
new file mode 100644
index 0000000..5a45f97
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_low_battery_image.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/icon_white_trigon.png b/app/src/main/res/drawable-xxxhdpi/icon_white_trigon.png
new file mode 100644
index 0000000..e0742b2
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/icon_white_trigon.png differ
diff --git a/app/src/main/res/drawable/shape16_light_green_color_bg.xml b/app/src/main/res/drawable/shape16_light_green_color_bg.xml
new file mode 100644
index 0000000..fc75cb9
--- /dev/null
+++ b/app/src/main/res/drawable/shape16_light_green_color_bg.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_live_v3.xml b/app/src/main/res/layout/activity_live_v3.xml
new file mode 100644
index 0000000..b726390
--- /dev/null
+++ b/app/src/main/res/layout/activity_live_v3.xml
@@ -0,0 +1,145 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/fragment_map_v3.xml b/app/src/main/res/layout/fragment_map_v3.xml
index a76f0cc..1914d67 100644
--- a/app/src/main/res/layout/fragment_map_v3.xml
+++ b/app/src/main/res/layout/fragment_map_v3.xml
@@ -10,10 +10,17 @@
android:layout_width="match_parent"
android:layout_height="match_parent" />
-
+
+
+
+
+
-
+ android:layout_marginTop="@dimen/dp_6"
+ android:visibility="gone" />
+ android:layout_marginBottom="@dimen/dp_38"
+ android:visibility="invisible" />
+ android:visibility="invisible">
-
@@ -9,11 +9,22 @@
-
+
+
+
+
diff --git a/app/src/main/res/layout/layout_map_device_battery.xml b/app/src/main/res/layout/layout_map_device_battery.xml
new file mode 100644
index 0000000..71a45b7
--- /dev/null
+++ b/app/src/main/res/layout/layout_map_device_battery.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/layout_pet_location_info.xml b/app/src/main/res/layout/layout_pet_location_info.xml
index c91b0e3..739b6e1 100644
--- a/app/src/main/res/layout/layout_pet_location_info.xml
+++ b/app/src/main/res/layout/layout_pet_location_info.xml
@@ -18,6 +18,7 @@
hours
Searching…
Keep tracker on and nearby to scan.
- Battery less than %s%%
+ Less than %s%%
Outside
Inside
7 Days Avg.
@@ -1050,5 +1050,8 @@
The program has an exception and is about to exit
Activate Subscription
+ Powered off
+ Near %s
+ Charging
\ No newline at end of file
diff --git a/baselibrary/src/main/java/com/abbidot/baselibrary/util/Utils.kt b/baselibrary/src/main/java/com/abbidot/baselibrary/util/Utils.kt
index fc161ee..1946d50 100644
--- a/baselibrary/src/main/java/com/abbidot/baselibrary/util/Utils.kt
+++ b/baselibrary/src/main/java/com/abbidot/baselibrary/util/Utils.kt
@@ -42,6 +42,8 @@ class Utils {
const val DATE_FORMAT_PATTERN_EN8 = "hh:mm a"
const val DATE_FORMAT_PATTERN_EN9 = "MMM d, yyyy hh:mm a"
const val DATE_FORMAT_PATTERN_EN10 = "dd/MM/yyyy HH:mm:ss"
+ const val DATE_FORMAT_PATTERN_EN11 = "dd/MM HH:mm"
+ const val DATE_FORMAT_PATTERN_EN12 = "dd/MM HH:mm:ss"
//返回星期几 简写
const val WEEK_FORMAT_PATTERN = "E"