From 8d1a44bf898906520f1d4b098933c153d991486b Mon Sep 17 00:00:00 2001 From: yezhiqiu <983577727@qq.com> Date: Fri, 24 Apr 2026 18:55:38 +0800 Subject: [PATCH] =?UTF-8?q?1.=E4=BC=98=E5=8C=96=E5=8C=BA=E5=88=86=E4=BF=A1?= =?UTF-8?q?=E5=8F=B7=E5=BC=B1/=E6=97=A0=E4=BF=A1=E5=8F=B7(4=E7=A7=8D?= =?UTF-8?q?=E7=8A=B6=E6=80=81=EF=BC=9A1.=20wifi=20zone=20=E4=B8=AD/?= =?UTF-8?q?=E5=85=B3=E6=9C=BA/=E4=BC=91=E7=9C=A0/=E5=85=85=E7=94=B5/?= =?UTF-8?q?=E8=B6=85=E6=97=B6=E6=97=A0=E4=B8=8A=E6=8A=A5-=E5=85=B3?= =?UTF-8?q?=EF=BC=8C2.=20=E4=BF=A1=E5=8F=B7=E5=A4=A7=E4=BA=8E50-=E5=BC=BA?= =?UTF-8?q?=EF=BC=8C=E4=BF=A1=E5=8F=B7=E5=A4=A7=E4=BA=8E0=E5=B0=8F?= =?UTF-8?q?=E4=BA=8E50=20-=E5=BC=B1=EF=BC=8C3.=20=E4=BF=A1=E5=8F=B7?= =?UTF-8?q?=E7=AD=89=E4=BA=8E0-=E6=97=A0)=202.=E4=BF=AE=E5=A4=8D=E5=9B=B4?= =?UTF-8?q?=E6=A0=8F=E7=BC=96=E8=BE=91=E5=92=8C=E6=B7=BB=E5=8A=A0=E4=BF=9D?= =?UTF-8?q?=E5=AD=98=E6=97=B6/=E5=88=A0=E9=99=A4=E6=97=B6=EF=BC=8C?= =?UTF-8?q?=E8=BF=98=E5=8F=AF=E4=BB=A5=E8=BE=93=E5=85=A5=E5=86=85=E5=AE=B9?= =?UTF-8?q?=E5=92=8C=E7=82=B9=E2=80=98=E5=8F=96=E6=B6=88=E2=80=99=E6=8C=89?= =?UTF-8?q?=E9=92=AE=203.=E4=BF=AE=E5=A4=8D=E5=88=A0=E9=99=A4=E5=9B=B4?= =?UTF-8?q?=E6=A0=8F=E6=97=B6=EF=BC=8C=E8=BF=98=E5=8F=AF=E4=BB=A5=E7=82=B9?= =?UTF-8?q?=E5=87=BB=E7=BC=96=E8=BE=91=E6=8C=89=E9=92=AE=204.=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E8=BD=A8=E8=BF=B9=E9=A1=B5=E9=9D=A2=E5=9B=B4=E6=A0=8F?= =?UTF-8?q?=E5=90=8D=E5=AD=97=E5=A4=AA=E9=95=BF=EF=BC=8C=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E5=AF=B9=E4=B8=8D=E9=BD=90=205.=E4=BF=AE=E5=A4=8D=E8=BD=A8?= =?UTF-8?q?=E8=BF=B9=E5=8F=AA=E6=9C=893=E4=B8=AA=E7=82=B9=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E6=BB=91=E5=9D=97=E6=BB=91=E4=B8=8D=E5=8A=A8=E7=9A=84?= =?UTF-8?q?bug=206.=E4=BF=AE=E5=A4=8D=E7=9B=B4=E6=92=AD=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E7=AC=AC=E4=B8=89=E4=B8=AA=E5=AF=BC=E8=88=AA=E6=97=A0=E6=B3=95?= =?UTF-8?q?=E7=82=B9=E5=87=BBbug=207.=E6=A0=A1=E5=AF=B9=E5=A4=9A=E8=AF=AD?= =?UTF-8?q?=E8=A8=80=E5=AD=97=E7=AC=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 6 +- .../adapter/SubscriptionHistoryAdapter.kt | 17 ++- .../tracker/bean/SubscriptionsOrderBean.kt | 2 + .../tracker/ui/activity/HomeV2Activity.kt | 3 +- .../tracker/ui/activity/SplashActivity.kt | 5 +- .../AddAndEditFencesZoneBaseActivity.kt | 43 +++++- .../fences/PreviewFencesZoneActivity.kt | 21 ++- .../tracker/ui/activity/map/LiveActivityV3.kt | 6 + .../tracker/ui/fragment/map/MapV3Fragment.kt | 97 +------------- .../com/abbidot/tracker/vm/MapViewModel.kt | 124 ++++++++++++++++-- .../tracker/widget/NoClickSlideSeekBar.java | 30 +++-- .../res/layout/item_history_fence_layout.xml | 1 + app/src/main/res/values-de/strings.xml | 82 ++++++++++-- app/src/main/res/values-zh-rCN/strings.xml | 93 +++++++++---- app/src/main/res/values/strings.xml | 53 ++++---- 15 files changed, 391 insertions(+), 192 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 9c71b9b..2ac1d6c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -29,8 +29,8 @@ android { minSdkVersion 23 targetSdkVersion 35 versionCode 2202 -// versionName "2.2.2" - versionName "2.2.2-Beta7" + versionName "2.2.2" +// versionName "2.2.2-Beta7" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -308,7 +308,7 @@ dependencies { //******************************************极光推送end******************************************************* //其中指代最新Bugly SDK版本号,也可以指定明确的版本号,例如4.0.0 - implementation 'com.tencent.bugly:crashreport:4.1.9.3' +// implementation 'com.tencent.bugly:crashreport:4.1.9.3' //其中latest.release指代最新Bugly NDK版本号,也可以指定明确的版本号,例如3.9.2 // implementation 'com.tencent.bugly:nativecrashreport:3.9.2' diff --git a/app/src/main/java/com/abbidot/tracker/adapter/SubscriptionHistoryAdapter.kt b/app/src/main/java/com/abbidot/tracker/adapter/SubscriptionHistoryAdapter.kt index f1a447d..1612985 100644 --- a/app/src/main/java/com/abbidot/tracker/adapter/SubscriptionHistoryAdapter.kt +++ b/app/src/main/java/com/abbidot/tracker/adapter/SubscriptionHistoryAdapter.kt @@ -46,6 +46,9 @@ class SubscriptionHistoryAdapter( } } + /** + * 保险订单 + */ private fun bindAnnualCareData(holder: BaseViewHolder, item: SubscriptionsOrderBean) { holder.setText( R.id.tv_subscription_annual_care_order_id, @@ -111,26 +114,28 @@ class SubscriptionHistoryAdapter( visibility = View.VISIBLE when (item.orderStatus) { 1 -> { - val updateTimestamp = Utils.stringToTimestamp(item.updateTime, isUtc = true) - val nowTimestamp = System.currentTimeMillis() +// val updateTimestamp = Utils.stringToTimestamp(item.updateTime, isUtc = true) +// val nowTimestamp = System.currentTimeMillis() if (item.enabled == ConstantInt.Type0 || (item.surplusDays == 0L && item.subscriptionStatus == ConstantInt.Close)) { visibility = View.GONE } else if (item.mealUnit == ConstantString.PackageUnitDay) { visibility = View.VISIBLE setText(R.string.txt_refund) } else if (item.mealUnit == ConstantString.PackageUnitMonth) { - val day7Timestamp = 7 * 24 * 60 * 60 * 1000L +// val day7Timestamp = 7 * 24 * 60 * 60 * 1000L //套餐超出7天不能退款 - if (nowTimestamp - updateTimestamp <= day7Timestamp) { +// if (nowTimestamp - updateTimestamp <= day7Timestamp) { + if (item.isRefundable == ConstantInt.Type1) { visibility = View.VISIBLE setText(R.string.txt_refund) } else { visibility = View.GONE } } else { - val day30Timestamp = 30 * 24 * 60 * 60 * 1000L +// val day30Timestamp = 30 * 24 * 60 * 60 * 1000L //套餐超出30天不能退款 - if (nowTimestamp - updateTimestamp <= day30Timestamp) { +// if (nowTimestamp - updateTimestamp <= day30Timestamp) { + if (item.isRefundable == ConstantInt.Type1) { visibility = View.VISIBLE setText(R.string.txt_refund) } else { diff --git a/app/src/main/java/com/abbidot/tracker/bean/SubscriptionsOrderBean.kt b/app/src/main/java/com/abbidot/tracker/bean/SubscriptionsOrderBean.kt index 96bdbfc..2de2c8b 100644 --- a/app/src/main/java/com/abbidot/tracker/bean/SubscriptionsOrderBean.kt +++ b/app/src/main/java/com/abbidot/tracker/bean/SubscriptionsOrderBean.kt @@ -55,6 +55,7 @@ data class SubscriptionsOrderBean( var endTime: Long, var refundTime: Long, var planTimeMonthsCount: Int, + var isRefundable: Int,//是否显示退款按钮 1:是 0:否 @MultipleEntity var menuType: Int, var isUpdateOrder: Int = 0//是否是升级订单 1:是 0:否 ) : Parcelable, MultiItemEntity { @@ -101,6 +102,7 @@ data class SubscriptionsOrderBean( 0L, 0L, 0, + 0, menuType, 0 ) 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 b4c7c1c..fb2f1e3 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 @@ -65,7 +65,6 @@ import com.hjq.permissions.XXPermissions import com.hjq.permissions.permission.PermissionLists import com.huantansheng.easyphotos.EasyPhotos import com.qmuiteam.qmui.widget.QMUITopBar -import com.tencent.bugly.crashreport.CrashReport import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -212,7 +211,7 @@ class HomeV2Activity : BaseActivity(ActivityHomeV2Binding mDataViewModel.getHomeBindPetList(this@HomeV2Activity) //设置bugly的用户id - CrashReport.setUserId(MMKVUtil.getString(MMKVKey.Email)) +// CrashReport.setUserId(MMKVUtil.getString(MMKVKey.Email)) //预先加载相册,防止上传头像几千张照片加载慢 XXPermissions.with(this).permission(PermissionLists.getReadMediaImagesPermission()) .request { _, deniedList -> diff --git a/app/src/main/java/com/abbidot/tracker/ui/activity/SplashActivity.kt b/app/src/main/java/com/abbidot/tracker/ui/activity/SplashActivity.kt index 4d64993..d053444 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/activity/SplashActivity.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/activity/SplashActivity.kt @@ -35,7 +35,6 @@ import com.baidu.mapapi.SDKInitializer import com.hjq.toast.Toaster import com.qmuiteam.qmui.arch.QMUIActivity import com.stripe.android.PaymentConfiguration -import com.tencent.bugly.crashreport.CrashReport import com.tencent.mm.opensdk.constants.ConstantsAPI import com.tencent.mm.opensdk.openapi.IWXAPI import java.util.Calendar @@ -220,8 +219,8 @@ class SplashActivity : QMUIActivity() { } //腾讯bugly初始化 - val buglyKey = Util.getMetadata(applicationContext, KeyNames.BUG_LY_KEY_NAME) - CrashReport.initCrashReport(applicationContext, buglyKey, AppUtils.isDebug()) +// val buglyKey = Util.getMetadata(applicationContext, KeyNames.BUG_LY_KEY_NAME) +// CrashReport.initCrashReport(applicationContext, buglyKey, AppUtils.isDebug()) } private fun initMapbox() { diff --git a/app/src/main/java/com/abbidot/tracker/ui/activity/device/fences/AddAndEditFencesZoneBaseActivity.kt b/app/src/main/java/com/abbidot/tracker/ui/activity/device/fences/AddAndEditFencesZoneBaseActivity.kt index f2b89f2..1e8587f 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/activity/device/fences/AddAndEditFencesZoneBaseActivity.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/activity/device/fences/AddAndEditFencesZoneBaseActivity.kt @@ -71,6 +71,9 @@ open class AddAndEditFencesZoneBaseActivity : var mFencesList: GetFencesBean? = null var isEditFences = false + //冻结点击 + private var isBlockedClick = false + private var mShowCenterLocationType = ConstantInt.OtherLocationType private val mDefaultFencesName = arrayOf("Home", "Office", "Garden", "Park", "Play", "Unsafe", "Vegetable Garden", "Water") @@ -211,6 +214,11 @@ open class AddAndEditFencesZoneBaseActivity : setFenceName() } + override fun leftBackOnClick() { + if (isBlockedClick) return + super.leftBackOnClick() + } + open fun mapLoadOk() { drawFences() } @@ -358,7 +366,7 @@ open class AddAndEditFencesZoneBaseActivity : override fun onRequestError(exceptionCode: String?) { super.onRequestError(exceptionCode) - setButtonEnabled(mViewBinding.btnSaveFencesZone, ConstantInt.Type1) + setDisableState(false) } }) } @@ -376,6 +384,11 @@ open class AddAndEditFencesZoneBaseActivity : R.string.txt_delete_success, isFinish = true, gravity = Gravity.CENTER ) } + + override fun onRequestError(exceptionCode: String?) { + super.onRequestError(exceptionCode) + setDisableState(false) + } }) } mFencesManageViewModel.mUpdateFenceLiveData.observe(this) { @@ -391,7 +404,7 @@ open class AddAndEditFencesZoneBaseActivity : override fun onRequestError(exceptionCode: String?) { super.onRequestError(exceptionCode) - setButtonEnabled(mViewBinding.btnSaveFencesZone, ConstantInt.Type1) + setDisableState(false) } }) } @@ -416,6 +429,23 @@ open class AddAndEditFencesZoneBaseActivity : showToast(resStringId, isFinish = true, gravity = Gravity.CENTER) } + /** + * 设置禁止状态 + */ + private fun setDisableState(isDisable: Boolean) { + isBlockedClick = isDisable + mViewBinding.apply { + if (isDisable) { + ilFencesZoneNameInput.etInputContent.isEnabled = false + setButtonEnabled(btnSaveFencesZone, ConstantInt.Type0) + } else { + ilFencesZoneNameInput.etInputContent.isEnabled = true + setButtonEnabled(btnSaveFencesZone, ConstantInt.Type1) + } + } + + } + override fun onWindowFocusChanged(hasFocus: Boolean) { super.onWindowFocusChanged(hasFocus) bottomMarginOverlap() @@ -659,7 +689,7 @@ open class AddAndEditFencesZoneBaseActivity : else ConstantInt.Type2 } mActionType = ConstantInt.Type0 - setButtonEnabled(mViewBinding.btnSaveFencesZone, ConstantInt.Type0) + setDisableState(true) name = fenceName when (fenceShapeType) { ConstantInt.CircleShapeType -> { @@ -687,13 +717,14 @@ open class AddAndEditFencesZoneBaseActivity : * 更新围栏 */ fun updateFences(fencesBean: FencesBean) { + if (isBlockedClick) return val fenceName = mViewBinding.ilFencesZoneNameInput.etInputContent.text.toString() if (TextUtils.isEmpty(fenceName)) { showToast(R.string.txt_not_null, gravity = Gravity.CENTER) return } mActionType = ConstantInt.Type1 - setButtonEnabled(mViewBinding.btnSaveFencesZone, ConstantInt.Type0) + setDisableState(true) mPetBean?.let { if (BleManager.getInstance().isConnected(it.macID)) { sendFenceData() @@ -746,12 +777,14 @@ open class AddAndEditFencesZoneBaseActivity : * 删除围栏 */ fun deleteFences(fencesBean: FencesBean) { + if (isBlockedClick) return ViewUtil.instance.showDialog( this, R.string.txt_delete_tips, object : BaseDialog.OnDialogOkListener { override fun onOkClick(dialog: BaseDialog<*>) { dialog.dismiss() mPetBean?.let { mActionType = ConstantInt.Type2 + setDisableState(true) if (BleManager.getInstance().isConnected(it.macID)) { //删除蓝牙标志 fencesBean.isOn = ConstantInt.Type2 @@ -884,7 +917,7 @@ open class AddAndEditFencesZoneBaseActivity : } tvFencesZoneShapeResetBtn -> recoverDefaultFencesView() - btnCancelFencesZone -> finish() + btnCancelFencesZone -> if (!isBlockedClick) finish() ivFencesZoneMapSwitchBtn -> switchMapType() } } diff --git a/app/src/main/java/com/abbidot/tracker/ui/activity/device/fences/PreviewFencesZoneActivity.kt b/app/src/main/java/com/abbidot/tracker/ui/activity/device/fences/PreviewFencesZoneActivity.kt index 95645cd..0e74ffd 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/activity/device/fences/PreviewFencesZoneActivity.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/activity/device/fences/PreviewFencesZoneActivity.kt @@ -57,6 +57,9 @@ class PreviewFencesZoneActivity : //操作类型,0增加,1编辑,2删除 private var mActionType = ConstantInt.Type1 + //冻结点击 + private var isBlockedClick = false + override fun getTopBar() = mViewBinding.previewFencesZoneTopBar.titleTopBar override fun initData() { @@ -129,6 +132,11 @@ class PreviewFencesZoneActivity : } } + override fun leftBackOnClick() { + if (isBlockedClick) return + super.leftBackOnClick() + } + override fun liveDataObserve() { //获取所有围栏返回 mFencesManageViewModel.mFencesLiveData.observe(this) { @@ -167,6 +175,11 @@ class PreviewFencesZoneActivity : XEventBus.post(EventName.DeleteFences) showToast(R.string.txt_delete_success, true, gravity = Gravity.CENTER) } + + override fun onRequestError(exceptionCode: String?) { + super.onRequestError(exceptionCode) + isBlockedClick = false + } }) } @@ -367,6 +380,7 @@ class PreviewFencesZoneActivity : * 删除围栏 */ private fun deleteFences() { + if (isBlockedClick) return ViewUtil.instance.showDialog( this, R.string.txt_delete_tips, object : BaseDialog.OnDialogOkListener { override fun onOkClick(dialog: BaseDialog<*>) { @@ -374,6 +388,7 @@ class PreviewFencesZoneActivity : mPetBean?.let { mCurrentFences?.apply { mActionType = ConstantInt.Type2 + isBlockedClick = true if (modeType == ConstantInt.Type3) modeType = ConstantInt.Type3 else if (BleManager.getInstance().isConnected(it.macID)) { //删除蓝牙标志 @@ -402,6 +417,7 @@ class PreviewFencesZoneActivity : } private fun goEditFences() { + if (isBlockedClick) return Util.checkLocationPermissionsGpsEnabled(this, { mCurrentFences?.apply { val intent = if (fenceType == ConstantInt.SafeZone) Intent( @@ -422,7 +438,10 @@ class PreviewFencesZoneActivity : btnPreviewFencesEdit -> goEditFences() mRightImageButton -> deleteFences() - cbPreviewFencesSwitch -> mCurrentFences?.apply { changeOnAndOff(this) } + cbPreviewFencesSwitch -> { + if (isBlockedClick) return + mCurrentFences?.apply { changeOnAndOff(this) } + } ivPreviewFencesMapSwitchBtn -> { mPreviewFencesMapCommon.switchSatelliteAndNormalMapType() 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 index 791dbef..44d8a1a 100644 --- 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 @@ -216,6 +216,7 @@ class LiveActivityV3 : BaseActivity(ActivityLiveV3Binding ilLiveV2OperateLayout.btnLiveV2Issue, ilMapLiveV2IssueLayout.tvCloseIssueBtn, ilLiveV3MapDeviceBatteryLayout.ivDeviceCloseBtn, + ilLiveV3MapPetLocation.ivPetLocationNavigationBtn, ilLiveV3MapDeviceMsg.ivDeviceMsgCloseBtn ) @@ -1258,6 +1259,11 @@ class LiveActivityV3 : BaseActivity(ActivityLiveV3Binding mMapDeviceBean?.isCloseMsg = true ilLiveV3MapDeviceMsg.root.visibility = View.GONE } + + ilLiveV3MapPetLocation.ivPetLocationNavigationBtn -> { + if (isLimitClick()) return + mMapViewModel.showNavigationDialog(this@LiveActivityV3, mMapDeviceBean) + } } } } 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 8e2d165..029a22c 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 @@ -11,7 +11,6 @@ import android.view.Gravity import android.view.View import androidx.activity.result.contract.ActivityResultContracts import androidx.core.content.ContextCompat -import androidx.core.net.toUri import androidx.core.view.WindowInsetsCompat import androidx.fragment.app.Fragment import androidx.fragment.app.commit @@ -28,20 +27,17 @@ 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.adapter.SelectMapListDialogAdapter import com.abbidot.tracker.base.BaseDialog import com.abbidot.tracker.base.BaseFragment import com.abbidot.tracker.bean.BleReportDataBean import com.abbidot.tracker.bean.BleTrackDeviceBean import com.abbidot.tracker.bean.DataBean import com.abbidot.tracker.bean.MapDeviceBean -import com.abbidot.tracker.bean.MenuTxtBean import com.abbidot.tracker.constant.ConstantInt import com.abbidot.tracker.constant.ConstantString import com.abbidot.tracker.constant.GetResultCallback import com.abbidot.tracker.databinding.FragmentMapV3Binding import com.abbidot.tracker.dialog.CommonDialog1 -import com.abbidot.tracker.dialog.SelectMapListDialog import com.abbidot.tracker.dialog.SelectMapTypeDialog import com.abbidot.tracker.ui.activity.HomeV2Activity import com.abbidot.tracker.ui.activity.map.LiveActivityV3 @@ -107,13 +103,6 @@ class MapV3Fragment : BaseFragment(FragmentMapV3Binding::i private var needGpsToGCJ02 = true private var mAnimatorSet: AnimatorSet? = null - private val mMapGooglePackageName = "com.google.android.apps.maps" - private val mMapGaoDePackageName = "com.autonavi.minimap" - private val mMapBaiduPackageName = "com.baidu.BaiduMap" - - private lateinit var mSelectMapListDialogAdapter: SelectMapListDialogAdapter - private var mSelectMapListDialog: SelectMapListDialog? = null - //一键定位开始的时间戳 private var notifyRefreshLocationTimestamp = 0L @@ -940,88 +929,6 @@ class MapV3Fragment : BaseFragment(FragmentMapV3Binding::i // } // } - private fun showNavigationDialog() { - if (null == mSelectMapListDialog) { - val mapList = mutableListOf() - ViewUtil.instance.addMenuBean( - mapList, - getString(R.string.map_navigate_map_google), - mMapGooglePackageName, - R.drawable.ico_map_google - ) - ViewUtil.instance.addMenuBean( - mapList, - getString(R.string.map_navigate_map_gaode), - mMapGaoDePackageName, - R.drawable.ico_map_gaode - ) - ViewUtil.instance.addMenuBean( - mapList, - getString(R.string.map_baidu_map), - mMapBaiduPackageName, - R.drawable.ico_map_gaode - ) - - mSelectMapListDialogAdapter = SelectMapListDialogAdapter(mContext!!, mapList) - mSelectMapListDialogAdapter.setOnItemClickListener(object : - BaseRecyclerAdapter.OnItemClickListener { - override fun onItemClick(itemView: View?, pos: Int) { - selectMapNavigation(mapList[pos]) - } - }) - mSelectMapListDialog = SelectMapListDialog(mContext!!, mSelectMapListDialogAdapter) - } - mSelectMapListDialog!!.show() - } - - /** - * 选择地图开始跳转 - */ - private fun selectMapNavigation(item: MenuTxtBean) { - mSelectMapListDialog?.dismiss() - mMapDeviceBean?.apply { - try { - when (item.menuValue) { - //谷歌地图 - mMapGooglePackageName -> { - var lat = latitude - var lon = longitude - if (MMKVUtil.getBoolean(MMKVKey.isGpsToGCJ02)) { - val convertLatLon = - LonAndLatUtil.convertFromWGS84ToGCJ02(latitude, longitude) - lat = convertLatLon[0] - lon = convertLatLon[1] - } - val uri = "google.navigation:q=${lat},${lon}&mode=w".toUri() - val intent = Intent(Intent.ACTION_VIEW, uri) - intent.setPackage(item.menuValue) - startActivity(intent) - } - //高德地图 https://lbs.amap.com/api/amap-mobile/guide/android/walk-navi - mMapGaoDePackageName -> { - val uri = "amapuri://openFeature?featureName=OnFootNavi&sourceApplication=${ - getString( - R.string.app_name - ) - }&lat=${latitude}&lon=${longitude}&dev=1".toUri() - val intent = Intent(Intent.ACTION_VIEW, uri) - intent.setPackage(item.menuValue) - startActivity(intent) - } - //百度地图 https://lbs.baidu.com/docs/webapi?title=mapadjustment/uri/andriod - mMapBaiduPackageName -> { - val uri = - "baidumap://map/direction?destination=name:|latlng:${latitude},${longitude}&mode=walking&coord_type=wgs84".toUri() - val intent = Intent(Intent.ACTION_VIEW, uri) - intent.setPackage(item.menuValue) - startActivity(intent) - } - } - } catch (e: Exception) { - showToast(getString(R.string.txt_no_install), gravity = Gravity.CENTER) - } - } - } override fun onClick(v: View?) { mViewBinding.apply { @@ -1094,7 +1001,9 @@ class MapV3Fragment : BaseFragment(FragmentMapV3Binding::i ilHomeMapPetLocation.ivPetLocationNavigationBtn -> { if (isLimitClick()) return // goNavigation() - showNavigationDialog() + getHomeV2Activity()?.let { + mMapViewModel.showNavigationDialog(it, mMapDeviceBean) + } } } } 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 fa9568b..2355038 100644 --- a/app/src/main/java/com/abbidot/tracker/vm/MapViewModel.kt +++ b/app/src/main/java/com/abbidot/tracker/vm/MapViewModel.kt @@ -1,23 +1,33 @@ package com.abbidot.tracker.vm import android.content.Context +import android.content.Intent import android.os.CountDownTimer +import android.view.Gravity import android.view.View import android.view.ViewGroup import androidx.appcompat.widget.AppCompatImageView import androidx.core.content.ContextCompat +import androidx.core.net.toUri import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import androidx.recyclerview.widget.RecyclerView +import com.abbidot.baselibrary.constant.MMKVKey import com.abbidot.baselibrary.list.BaseRecyclerAdapter +import com.abbidot.baselibrary.util.MMKVUtil import com.abbidot.baselibrary.util.Utils import com.abbidot.tracker.R +import com.abbidot.tracker.adapter.SelectMapListDialogAdapter +import com.abbidot.tracker.base.BaseActivity import com.abbidot.tracker.bean.DataBean import com.abbidot.tracker.bean.MapDeviceBean +import com.abbidot.tracker.bean.MenuTxtBean import com.abbidot.tracker.bean.PetBean import com.abbidot.tracker.constant.ConstantInt +import com.abbidot.tracker.dialog.SelectMapListDialog import com.abbidot.tracker.retrofit2.NetworkApi +import com.abbidot.tracker.util.LonAndLatUtil import com.abbidot.tracker.util.Util import com.abbidot.tracker.util.ViewUtil import com.abbidot.tracker.util.bluetooth.SRBleUtil @@ -39,6 +49,13 @@ class MapViewModel : ViewModel() { var mDeviceMsgType = ConstantInt.SpecialType + private val mMapGooglePackageName = "com.google.android.apps.maps" + private val mMapGaoDePackageName = "com.autonavi.minimap" + private val mMapBaiduPackageName = "com.baidu.BaiduMap" + private var mSelectMapListDialogAdapter: SelectMapListDialogAdapter? = null + private var mSelectMapListDialog: SelectMapListDialog? = null + private var mMapDeviceBean: MapDeviceBean? = null + fun setupRefreshLocation(deviceId: String) { viewModelScope.launch { val result = NetworkApi.setupRefreshLocation(deviceId) @@ -185,7 +202,10 @@ class MapViewModel : ViewModel() { } } //网络无信号/ 分钟后无上报所有绿点取消显示 - else if (lteSignal <= ConstantInt.NoSignal || Util.isTimeoutReport(updateTime,gnssInterval)) { + else if (lteSignal <= ConstantInt.NoSignal || Util.isTimeoutReport( + updateTime, gnssInterval + ) + ) { // setNoState(context, deviceStateList) //警告状态 @@ -307,7 +327,7 @@ class MapViewModel : ViewModel() { ) { mapDeviceBean.let { //是否超时上报 - val isTimeoutReport = Util.isTimeoutReport(it.updateTime,it.gnssInterval) + val isTimeoutReport = Util.isTimeoutReport(it.updateTime, it.gnssInterval) deviceStateList[0].apply { menuType = ConstantInt.Open val lteValue = @@ -322,14 +342,12 @@ class MapViewModel : ViewModel() { deviceStateList[1].apply { menuType = ConstantInt.Open val gpsValue = - if (isTimeoutReport || it.powerSwitch == ConstantInt.Type0 || it.powerSwitch == ConstantInt.Type2 || it.inWifiZone == ConstantInt.Type1) { + if (isTimeoutReport || it.powerSwitch == ConstantInt.Type0 || it.powerSwitch == ConstantInt.Type2 || it.powerSwitch == ConstantInt.Type3 || it.inWifiZone == ConstantInt.Type1) { menuType = ConstantInt.Close context.getString(R.string.tracker_manage_set_led_off) - } else if (it.gpsSignal > ConstantInt.WeakSignal) { - context.getString(R.string.txt_strong_signal) - } else { - context.getString(R.string.txt_weak_signal) - } + } else if (it.gpsSignal > ConstantInt.WeakSignal) context.getString(R.string.txt_strong_signal) + else if (it.gpsSignal == ConstantInt.NoSignal) context.getString(R.string.txt_no_signal) + else context.getString(R.string.txt_weak_signal) value = context.getString(R.string.tracker_manage_set_gps) + ":$gpsValue" } deviceStateList[2].apply { @@ -550,6 +568,96 @@ class MapViewModel : ViewModel() { } } + /** + * 显示导航地图 + */ + fun showNavigationDialog(activity: BaseActivity<*>, mapDeviceBean: MapDeviceBean?) { + mMapDeviceBean = mapDeviceBean + if (null == mSelectMapListDialog) { + val mapList = mutableListOf() + ViewUtil.instance.addMenuBean( + mapList, + activity.getString(R.string.map_navigate_map_google), + mMapGooglePackageName, + R.drawable.ico_map_google + ) + ViewUtil.instance.addMenuBean( + mapList, + activity.getString(R.string.map_navigate_map_gaode), + mMapGaoDePackageName, + R.drawable.ico_map_gaode + ) + ViewUtil.instance.addMenuBean( + mapList, + activity.getString(R.string.map_baidu_map), + mMapBaiduPackageName, + R.drawable.ico_map_gaode + ) + + mSelectMapListDialogAdapter = SelectMapListDialogAdapter(activity, mapList).apply { + setOnItemClickListener(object : BaseRecyclerAdapter.OnItemClickListener { + override fun onItemClick(itemView: View?, pos: Int) { + selectMapNavigation(activity, mapList[pos]) + } + }) + } + mSelectMapListDialog = SelectMapListDialog(activity, mSelectMapListDialogAdapter!!) + } + mSelectMapListDialog?.show() + } + + /** + * 选择地图开始跳转 + */ + private fun selectMapNavigation(activity: BaseActivity<*>, item: MenuTxtBean) { + mSelectMapListDialog?.dismiss() + mMapDeviceBean?.apply { + try { + when (item.menuValue) { + //谷歌地图 + mMapGooglePackageName -> { + var lat = latitude + var lon = longitude + if (MMKVUtil.getBoolean(MMKVKey.isGpsToGCJ02)) { + val convertLatLon = + LonAndLatUtil.convertFromWGS84ToGCJ02(latitude, longitude) + lat = convertLatLon[0] + lon = convertLatLon[1] + } + val uri = "google.navigation:q=${lat},${lon}&mode=w".toUri() + val intent = Intent(Intent.ACTION_VIEW, uri) + intent.setPackage(item.menuValue) + activity.startActivity(intent) + } + //高德地图 https://lbs.amap.com/api/amap-mobile/guide/android/walk-navi + mMapGaoDePackageName -> { + val uri = "amapuri://openFeature?featureName=OnFootNavi&sourceApplication=${ + activity.getString( + R.string.app_name + ) + }&lat=${latitude}&lon=${longitude}&dev=1".toUri() + val intent = Intent(Intent.ACTION_VIEW, uri) + intent.setPackage(item.menuValue) + activity.startActivity(intent) + } + //百度地图 https://lbs.baidu.com/docs/webapi?title=mapadjustment/uri/andriod + mMapBaiduPackageName -> { + val uri = + "baidumap://map/direction?destination=name:|latlng:${latitude},${longitude}&mode=walking&coord_type=wgs84".toUri() + val intent = Intent(Intent.ACTION_VIEW, uri) + intent.setPackage(item.menuValue) + activity.startActivity(intent) + } + } + } catch (e: Exception) { + activity.showToast( + activity.getString(R.string.txt_no_install), gravity = Gravity.CENTER + ) + } + } + } + + /** * 停止获取数据 */ diff --git a/app/src/main/java/com/abbidot/tracker/widget/NoClickSlideSeekBar.java b/app/src/main/java/com/abbidot/tracker/widget/NoClickSlideSeekBar.java index 2156bf7..ad4a118 100644 --- a/app/src/main/java/com/abbidot/tracker/widget/NoClickSlideSeekBar.java +++ b/app/src/main/java/com/abbidot/tracker/widget/NoClickSlideSeekBar.java @@ -27,6 +27,8 @@ public class NoClickSlideSeekBar extends AppCompatSeekBar { private Rect mThumbRect; private int mX, mY; + //是否可以滑动 + private boolean isCanSile = true; private NoClickSlideSeekBar(Context context) { super(context); @@ -42,22 +44,28 @@ public class NoClickSlideSeekBar extends AppCompatSeekBar { @Override public boolean onTouchEvent(MotionEvent event) { - if (MotionEvent.ACTION_DOWN == event.getAction()) { + isCanSile = true; mThumbRect = getThumb().getBounds(); - } - mX = (int) event.getX(); - mY = (int) event.getY(); + mX = (int) event.getX(); + mY = (int) event.getY(); + + if (mStaus == STATUS.STATUS_CLICK && !checkBound()) { + isCanSile = false; + return true; + } + if (mStaus == STATUS.STATUS_SLIDE && checkBound()) { + isCanSile = false; + return true; + } + if (mStaus == STATUS.STATUS_UNABLE) { + isCanSile = false; + return true; + } - if (mStaus == STATUS.STATUS_CLICK && !checkBound()) { - return true; } - if (mStaus == STATUS.STATUS_SLIDE && checkBound()) { + if (!isCanSile) return true; - } - if (mStaus == STATUS.STATUS_UNABLE) { - return true; - } return super.onTouchEvent(event); } diff --git a/app/src/main/res/layout/item_history_fence_layout.xml b/app/src/main/res/layout/item_history_fence_layout.xml index 6ce0a35..e7ba63b 100644 --- a/app/src/main/res/layout/item_history_fence_layout.xml +++ b/app/src/main/res/layout/item_history_fence_layout.xml @@ -28,6 +28,7 @@ android:layout_below="@id/tv_history_fence_type_time" android:layout_alignStart="@id/tv_history_fence_type_time" android:layout_marginTop="@dimen/dp_6" + android:gravity="start" android:text="@string/app_name" android:textColor="@color/select_color3" android:textSize="@dimen/textSize14" diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 9986c75..15c0f15 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -43,7 +43,6 @@ Bindung Abgeschlossen - Copyright © %d ABBIDOT All rights reserved Daten Karte Profil @@ -374,7 +373,7 @@ %s%% Rechtliche Informationen Willkommen in der Abbidot App! Um Ihre Rechte besser zu schützen, erläutern wir in dieser Datenschutzerklärung, wie wir Ihre Daten erfassen, nutzen, verarbeiten und schützen. Bitte lesen Sie die Datenschutzerklärung und Nutzungsbedingungen sorgfältig. - Datenschutzerklärung & Nutzungsbedingungen akzeptieren + Datenschutzerklärung & AGB Ich akzeptiere Ablehnen Keine Download-Adresse @@ -556,8 +555,8 @@ Neuen Tracker hinzufügen Laden und einschalten Schritt 1: - Laden Sie den Tracker zuerst auf; rotes Licht leuchtet. - Kabel abziehen, 3 grüne Blitze – Gerät eingeschaltet. + Tracker laden; 3 weiße Lampen blinken, dann leuchtet rot dauerhaft. + Kabel abziehen; langsames grünes Blinken zeigt an, dass das Gerät eingeschaltet ist. Schritt 2: Suche nach Tracker Halten Sie das Telefon nahe an den Tracker. @@ -575,10 +574,10 @@ Vorteile Monatliches Abonnement $%s - /pro Monat - /pro Jahr - $%s/pro Monat - $%s/pro Jahr + /Monat + /Jahr + $%s/Monat + $%s/Jahr Beliebt Plan bestätigen Gerätenummer @@ -621,7 +620,7 @@ Dauerhafter Wohnort spart Energie, verbessert Ortung. Ist dies das Zuhause Ihres Haustieres? Dauerhafter Wohnsitz - WLAN-Netzwerk wählen, kein Passwort nötig. + WLAN-Netzwerk wähle Später Welche Maßeinheiten für Ihr Haustier? Größe Ihres Haustieres @@ -865,7 +864,7 @@ Abgelaufen Tarif upgraden Restwert - /Monat x%s + Monat x%s (Verlängerung zu $%s jährlich danach) (Verlängerung zu $%s monatlich danach) Haustiere orten und trainieren, um Verlust/Gefahren vorzubeugen. @@ -891,12 +890,12 @@ Falsches Passwort. Bitte erneut versuchen. Ihr Zugriff ist abgelaufen. „%s“ lädt dich ein, den Status von „%s“ zu prüfen. - Solange der Tracker deinen Buddy sicher in der Energiesparzone erkennt, bleiben LIVE-Tracking, Licht und Ton aus. + Solange der Tracker deinen Buddy sicher in der Energiesparzone erkennt, bleiben LIVE-Tracking, Licht und Ton aus. Info zur Tracking-Dauer Ihr Abonnement ist abgelaufen. Bitte aufladen. %s Geofences gesetzt %s ist in der Nähe - Tracker nur löschen, wenn du ihn zurückgibst oder weitergibst. + Nur wenn du deinen Tracker zurückgibst oder weitergibst, solltest du ihn von deinem Konto entkoppeln. Wird gelöscht LED-Einstellung Reserve @@ -921,5 +920,64 @@ E-Mail-Adresse eingeben. Wi-Fi gewährleistet Tracker-Verbindung bei schwachem LTE. Updated: %s + 1-Jahres-Abonnement + 2-Jahres-Abonnement + 3-Jahres-Abonnement + Schon ab + Zahlungsmanager + Jährliche Abrechnung + Basisplan + Premiumplan + Echtzeitverfolgung + Aktivitäts-/Ruheprotokolle + Benachrichtigungen bei Notfällen + Anpassbare LED + Geofencing + Routenverlauf + Teilen mit Familienmitgliedern + Premium-Kundensupport + Das Programm hat eine Ausnahme und wird beendet + Abo aktivieren + Ausgeschaltet + In der Nähe von %s + Lädt + Gesamtzeit + Live funktioniert nur über Mobilfunk + Gerät entkoppeln + Profil bearbeiten + Keine Internetverbindung + /Tag + Verlängerung: $%s/%s Tag am %s + /Tag x%s + Die ABBIDOT-App sammelt Standortdaten. Die Route und Entfernung zwischen dem aktuellen Standort und dem Gerät können berechnet werden. + (Verlängerung für $%s pro %s Tag danach) + (Verlängerung für $%s/%s Tage danach) + (Verlängerung für $%s/%s Jahre danach) + (Verlängerung für $%s/%s Monate danach) + Systemfehler: Bitte später erneut versuchen. + Fehlende Parameter. + Tracker beschäftigt. Bitte warten und erneut versuchen. + Tracker offline. Vorgang nicht möglich. + Live-Stream läuft. Einstellungen nicht verfügbar. + Vorgang fehlgeschlagen. Bitte erneut versuchen. + Ortsbestimmung… + Ton + Ortung funktioniert nur über Mobilfunk + Haustier ist in der Nähe, Radar versuchen + Ziehen zum Laden weiterer Inhalte + Loslassen zum Laden + Voll aufgeladen + Vor %@ eingeschlafen + Bewegen Sie %@ zum Aufwecken + Zeitleiste + Halten Sie das Telefon nah ans Gerät + Auto-Verlängerung: Kündigen + %s-Jahres-Garantie + Ablaufdatum: + 1 Austausch pro Jahr, aus jedem Grund + Bluetooth Radar + espeichert. Aktiv, wenn online. + Verlängerung: $%s / %s Jahre am %s + Verlängerung: $%s / %s Monate am %s \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index d478deb..e5491d9 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -40,9 +40,9 @@ 中国 日本 - - + + 已有设备? 还没有 @@ -127,7 +127,7 @@ 输入设备ID 激活 - 激活设备以继续 + 激活设备并继续 不用了,谢谢 激活 我的设备 @@ -160,7 +160,7 @@ 邀请 邀请成功,请通知你的家人 返回 - 追踪时间 + 追踪间隔 关机 围栏 围栏详情 @@ -260,7 +260,7 @@ 您的设备已过期,请充值 确定要解绑宠物? - 停止监控宠物轨迹? + 停止直播? 确定要分享\'%s\'的宠物数据 确定要添加此宠物吗? 删除 @@ -441,7 +441,7 @@ 升级中 准备升级 设备连接成功 - 当前是最新版本 + 已是最新版本 该设备已被绑定 活动 路线 @@ -599,8 +599,8 @@ 添加追踪器 充电并开机 第一步: - 先为追踪器充电,红灯亮起 - 拔掉充电线后绿灯闪烁3次——设备已启动 + 先给追踪器充电;三个白色灯闪烁,红灯亮起。 + 拔掉电缆,一个绿灯闪烁,设备已开启。 第二步: 搜索追踪器 将手机靠近追踪器 @@ -664,7 +664,7 @@ 常住地点可省电并优化定位。 这是您宠物的家吗? 常住地点 - 选择Wi-Fi网络,无需密码。 + 选择Wi-Fi网络 稍后 您宠物的计量单位是? 您宠物的身高 @@ -738,7 +738,7 @@ 小时 (hours) 正在搜索… 请保持追踪器开机并在附近以便扫描。 - 电量低于%s%% + 电量低于 %s%% 户外 室内 7日均值 @@ -765,7 +765,7 @@ 无信号 WiFi 选择计量单位 - 公制 (厘米, 千克) + 公制 (厘米, 千克) 英制 (英寸, 磅) 公里/小时 (km/h) 英里/小时 (mph) @@ -824,7 +824,7 @@ 摇尾探险家 (Tailwag Explorer) 超棒拍档 (Pawsome Partner) 一年抱抱族 (1 Year Hugger) - 喵不可言 (Purrfect Partner - 适用于猫) / 汪星挚友 (适用于狗) + 汪星挚友(Purrfect Partner) 两年同伴 (2 Year Companion) 忠实好友 (Faithful Friend) 三载和谐 (3 Year Harmony) @@ -939,7 +939,7 @@ 您的订阅已过期,请续费 %s 围栏设置 %s 在附近 - 仅在您要退回或赠送追踪器时,才将其从您的账户中删除。 + 仅在您要退回或赠送追踪器时,才将其从您的账户中解绑。 将被删除 LED灯设置 预留 @@ -964,15 +964,64 @@ 请输入邮箱。 当LTE信号弱时,Wi-Fi可确保追踪器保持连接 更新于:%s + 1年订阅 + 2年订阅 + 3年订阅 低至 - APP出现异常,即将退出! - 系统异常 - 缺少参数 - Tracker设备繁忙,还有之前的下发任务未完成 - Tracker设备未在线 - Tracker启动了Live直播 - 其他异常 - 上拉加载更多 - 松手加载更多 + 支付管理 + 按年计费 + 基础计划 + 高级计划 + 实时追踪 + 活动/休息 + 紧急情况日志 + 自定义LED灯 + 地理围栏 + 路线历史记录 + 家庭成员共享 + 高级客户支持 + 程序出现异常,即将退出 + 激活订阅 + 已关机 + 靠近%s + 充电中 + 总时间 + 直播仅限蜂窝网络 + 解绑设备 + 编辑资料 + 无网络连接 + /天 + 续费:$%s/%s天,于%s + /天 x%s + ABBIDOT应用收集位置数据,可计算当前位置与设备之间的路线和距离。 + (之后按$%s每%s天续费) + (之后按$%s/%s天续费) + (之后按$%s/%s年续费) + (之后按$%s/%s月续费) + 系统错误:请稍后重试。 + 缺少参数。 + 定位器繁忙,请稍后重试。 + 定位器离线,无法继续。 + 直播进行中,设置不可用。 + 操作失败,请重试。 + 定位中… + 提示音 + 定位仅适用于蜂窝网络 + 宠物靠近,请尝试雷达 + 下拉加载更多 + 释放加载 + 已充满电 + %s前进入休眠 + 移动%s以唤醒 + 时间线 + 保持手机靠近设备 + 自动续订:取消 + %s 年保险 + 到期时间: + 每年 1 次换新,任何原因均可 + 蓝牙雷达 + 已保存,上线时生效。 + 续订:$%s / %s 年,于 %s + 续订:$%s / %s 月,于 %s \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 251627e..68a8c87 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -97,9 +97,9 @@ 86 81 - - + + Already have a GPS Tracker? Not yet @@ -262,7 +262,7 @@ Google Map Gaode Map Cancel - Install the map app to navigate + The APP is not installed, please download and install the app first Active Time Goal @@ -796,7 +796,7 @@ hours Searching… Keep tracker on and nearby to scan. - Less than %s%% + Battery less than %s%% Outside Inside 7 Days Avg. @@ -823,7 +823,7 @@ No signal WiFi Select measurement unit - Metric(cm, kg) + Metric(cm, kg) Imperial(in, lb) km/h mph @@ -941,12 +941,12 @@ Renewal: $%s/month on %s Renewal: /month on - Replacement Coverage + Annual Care Protection $12.90/year for peace of mind and easy 1-unit replacement annually. Replacement Guarantee Enter discount code Check - Replacement Coverage + Annual Care Annual Care: Bluetooth connection failed LED Light Settings @@ -1008,7 +1008,7 @@ Delete successfully Edit Payment Method Sure to delete this card? - Account exists. Log in now? + Account exists. Log in now? Selected date is out of range Shake to wake your tracker next time. Turn on the tracker, open the app, go to \'Pet\' > \'Tracker\' on the dashboard, then tap \'Network\', \'GPS\', \'Battery\', \'WiFi zone\', \'Bluetooth\', or \'Light\' to check connectivity, signal, or battery status. @@ -1022,6 +1022,9 @@ Please enter email address. Wi-Fi ensures your tracker stays connected when LTE signals are weak. Updated: %s + 1 Year Subscription + 2 Year Subscription + 3 Year Subscription As low as Payment Manager Billed annually @@ -1031,42 +1034,34 @@ Activity/Resting Logs Notifications for Emergencies Customized LED - Bluetooth Radar Geofencing Route History Records Family Members Sharing Premium Customer Support - Renewal: $%s/%s years on %s - Renewal: $%s/%s months on %s - 1 replacement/year, any reason - Expiry Time: - %s Year Care - Saved. Active when online. The program has an exception and is about to exit Activate Subscription Powered off Near %s Charging - Total Time Live works on cellular only Unbind Device Edit Profile No internet connection + /day + Renewal: $%s/%s day on %s + /day x%s + ABBIDOT APP collects location data,The route and distance between the current location and the device can be calculated. + (Renew at $%s per %s day thereafter) + (Renew at $%s/%s days thereafter) + (Renew at $%s/%s years thereafter) + (Renew at $%s/%s months thereafter) System Error: Please try again later. Missing Parameters. Tracker Busy. Please wait and retry. Tracker Offline. Unable to proceed. Live stream in progress. Settings unavailable. Operation failed. Please try again. - /day - Renewal: $%s/%s day on %s - /day x%s - "ABBIDOT APP collects location data,The route and distance between the current location and the device can be calculated." - (Renew at $%s per day thereafter) - (Renew at $%s/%s days thereafter) Locating… - (Renew at $%s/%s years thereafter) - (Renew at $%s/%s months thereafter) Tone Locate works on cellular only Pet is close, try Radar @@ -1075,9 +1070,17 @@ Fully charged Fell asleep %s ago Move %s to wake up - Baidu Map Timeline Keep phone close to device Auto-Renew: Cancel + %s Year Care + Expiry Time: + 1 replacement/year, any reason + Total Time + Bluetooth Radar + Saved. Active when online. + Renewal: $%s/%s years on %s + Renewal: $%s/%s months on %s + Baidu Map \ No newline at end of file