From 5be446af729294b60b28e3fbb36b3c6029f8bd3f Mon Sep 17 00:00:00 2001 From: yezhiqiu <983577727@qq.com> Date: Thu, 7 May 2026 12:02:55 +0800 Subject: [PATCH] =?UTF-8?q?1.map=E5=92=8C=E7=9B=B4=E6=92=AD=E9=A1=B5?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=94=A8=E6=88=B7=E5=92=8C=E5=AE=A0=E7=89=A9?= =?UTF-8?q?=E8=99=9A=E7=BA=BF=E8=AE=BE=E7=BD=AE=202.=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E5=B8=AE=E5=8A=A9=E9=A1=B5=E9=9D=A2=203.=E6=94=AF=E4=BB=98?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E5=8E=BB=E6=8E=89=E7=A8=8E=E7=9A=84=E8=AE=A1?= =?UTF-8?q?=E7=AE=97=204.GPS:=20Off=20=E6=94=B9=E4=B8=BAGPS:=20Sleep;=205.?= =?UTF-8?q?map=E9=A1=B5=E5=A2=9E=E5=8A=A0=E4=BD=8D=E7=BD=AE=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E6=97=B6=E9=97=B4=E6=A0=BC=E5=BC=8F=EF=BC=9A=E5=BD=93?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=BB=9E=E5=90=8E=E8=B6=85=E8=BF=872?= =?UTF-8?q?=E5=80=8D=E7=9A=84=E4=B8=8A=E6=8A=A5=E9=97=B4=E9=9A=94=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E6=89=8D=E6=98=BE=E7=A4=BA=20(2h=2035m=20ago)?= =?UTF-8?q?=E2=80=9D=EF=BC=8C=E6=98=BE=E7=A4=BA=E4=BC=91=E7=9C=A0=E4=B8=AD?= =?UTF-8?q?=E6=97=B6=EF=BC=8C=E4=B8=8D=E6=98=BE=E7=A4=BA=E2=80=9C(2h=2035m?= =?UTF-8?q?=20ago=EF=BC=89=206.=E8=BF=90=E5=8A=A8=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E6=9F=A5=E7=9C=8B30=E5=A4=A9=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=207.=E5=8E=86=E5=8F=B2=E8=BD=A8=E8=BF=B9=E9=99=90?= =?UTF-8?q?=E5=88=B6=E5=8F=AA=E8=83=BD=E7=9C=8B30=E5=A4=A9=E6=95=B0?= =?UTF-8?q?=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 6 +- .../subscription_terms_conditions_en.html | 57 ++++++++++++++----- .../tracker/dialog/SelectMapTypeDialog.kt | 17 +++++- .../dialog/ShowCalenderAndTimeDialog.kt | 37 +++++++++--- .../tracker/dialog/ShowCalenderDialog.kt | 2 +- .../ui/activity/data/MoreActivityActivity.kt | 2 +- .../ui/activity/data/MoreSleepActivity.kt | 2 +- .../help/HelpCreatePetFenceActivity.kt | 27 +++++++-- .../help/HelpTrackerStatusActivity.kt | 41 ++++++++++++- .../ui/activity/help/HowWorkActivity.kt | 29 +++++++++- .../tracker/ui/activity/map/LiveActivityV3.kt | 26 +++++++-- .../subscribe/SureSubscriptionPlanActivity.kt | 20 ++++--- .../tracker/ui/common/map/HomeMapCommonV3.kt | 9 ++- .../ui/fragment/data/RouteV3Fragment.kt | 6 +- .../ui/fragment/device/HomeTrackFragment.kt | 4 +- .../tracker/ui/fragment/map/MapV3Fragment.kt | 47 ++++++++++++--- .../map/googlemap/BaseGoogleMapFragment.kt | 7 ++- .../googlemap/HomeMapGoogleMapFragmentV3.kt | 47 +++++++++------ .../java/com/abbidot/tracker/util/ViewUtil.kt | 7 ++- .../com/abbidot/tracker/vm/MapViewModel.kt | 43 ++------------ .../calender/HorizontalCalenderViewV2.java | 3 +- .../res/layout/activity_help_power_on_off.xml | 25 +++++++- .../layout/activity_help_tracker_status.xml | 4 +- .../layout/dialog_select_map_type_layout.xml | 10 ++-- .../layout/item_subscribe_summary_layout.xml | 2 +- .../res/layout/layout_pet_location_info.xml | 9 +++ app/src/main/res/values-de/strings.xml | 13 ++++- app/src/main/res/values-zh-rCN/strings.xml | 9 +++ app/src/main/res/values/colors.xml | 1 + app/src/main/res/values/strings.xml | 31 +++++++--- .../abbidot/baselibrary/constant/MMKVKey.kt | 2 + .../com/abbidot/baselibrary/util/Utils.kt | 35 ++++++++++++ 32 files changed, 433 insertions(+), 147 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 36e0f28..43980d0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -28,9 +28,9 @@ android { applicationId "com.abbidot.tracker" minSdkVersion 23 targetSdkVersion 35 - versionCode 2203 -// versionName "2.2.3" - versionName "2.2.3-Beta1" + versionCode 2204 +// versionName "2.2.4" + versionName "2.2.4-Beta1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/assets/subscription_terms_conditions_en.html b/app/src/main/assets/subscription_terms_conditions_en.html index 90afc2a..b551e25 100644 --- a/app/src/main/assets/subscription_terms_conditions_en.html +++ b/app/src/main/assets/subscription_terms_conditions_en.html @@ -2,19 +2,50 @@
-

ABBIDOT Tracker Subscription Terms and Conditions -

-

1.Subscription Plans Users can choose between Basic and Prime plans. Basic plan subscribers can upgrade to Prime at any time. Prime plan subscribers can't change to Basic plan. - -

2.Refund Policy Automatic Refund (Within 48 Hours): Full refund available if canceled within 48 hours of subscription. Processed automatically without manual review. Manual Refund (After 48 Hours): For subscriptions older than 48 hours but within 1 month, refunds require manual approval. Eligibility: Only applicable to annual (1-year) subscriptions. Refunds may be prorated based on usage. No Refund After 1 Month: Subscriptions active for over 1 month are non-refundable.

- -

3.Pausing Subscription & Number Retention Users may pause their subscription. Number Retention: Paused numbers can be retained for up to 1 year. A small fee will apply for number retention during the pause period. Failure to reactivate within 1 year may result in number release.

- -

4.Modifications ABBIDOT reserves the right to update these terms. Users will be notified of changes. By subscribing, you agree to these terms.

- -

For support contact:

-

support@abbidot.com

- +

ABBIDOT Tracker Subscription Terms and Conditions

+
+

1. Subscription Plans

+

ABBIDOT offers three subscription plans:

+ +

All subscriptions are automatically renewed at the end of each billing cycle unless canceled by the user.

+

Users may cancel their subscription at any time. After cancellation, the subscription will remain active until the end of the current billing period, and no further charges will be applied.

+

The device will continue to function normally during the active subscription period.

+
+

2. Refund Policy

+

2.1 Automatic Refund (Within 48 Hours)

+

All subscription purchases are eligible for a full automatic refund within 48 hours of payment. Refunds will be processed automatically without manual review.

+
+

2.2 Standard Refund Window (30 Days)

+

After the initial 48-hour period, users may request a refund within 30 days of purchase.

+ +
+

2.3 No Refund After 30 Days

+

Subscriptions older than 30 days are non-refundable.

+
+

3. Subscription Cancellation

+

Users may cancel their subscription at any time.

+ +
+

4. Policy Updates

+

ABBIDOT reserves the right to update or modify these Terms and Conditions at any time. Users will be notified of significant changes.

+

By subscribing to ABBIDOT services, you agree to these terms.

+
+

5. Customer Support

+

If you encounter any difficulties, please contact us at:

+

subscription@abbidot.com

+

Our support team will assist you as soon as possible.

diff --git a/app/src/main/java/com/abbidot/tracker/dialog/SelectMapTypeDialog.kt b/app/src/main/java/com/abbidot/tracker/dialog/SelectMapTypeDialog.kt index 6bbd827..456b98d 100644 --- a/app/src/main/java/com/abbidot/tracker/dialog/SelectMapTypeDialog.kt +++ b/app/src/main/java/com/abbidot/tracker/dialog/SelectMapTypeDialog.kt @@ -2,8 +2,10 @@ package com.abbidot.tracker.dialog import android.content.Context import android.widget.CompoundButton +import com.abbidot.baselibrary.constant.MMKVKey import com.abbidot.baselibrary.list.BaseRecyclerAdapter import com.abbidot.baselibrary.util.AppUtils +import com.abbidot.baselibrary.util.MMKVUtil import com.abbidot.tracker.base.BaseDialog import com.abbidot.tracker.bean.DataBean import com.abbidot.tracker.databinding.DialogSelectMapTypeLayoutBinding @@ -18,12 +20,14 @@ import com.abbidot.tracker.util.ViewUtil class SelectMapTypeDialog( context: Context, adapter: BaseRecyclerAdapter<*>, - checkedChangeListener: CompoundButton.OnCheckedChangeListener? = null + fenceCheckedChangeListener: CompoundButton.OnCheckedChangeListener? = null, + dashedCheckedChangeListener: CompoundButton.OnCheckedChangeListener? = null ) : BaseDialog( DialogSelectMapTypeLayoutBinding::inflate, context ) { private var mAdapter = adapter - private val mCheckedChangeListener = checkedChangeListener + private val mFenceCheckedChangeListener = fenceCheckedChangeListener + private val mDashedCheckedChangeListener = dashedCheckedChangeListener override fun initView() { mViewBinding.apply { @@ -31,7 +35,10 @@ class SelectMapTypeDialog( context, rvShowMapTypeList, mAdapter, right = AppUtils.dpToPx(58) ) cbDialogMapFencesSwitch.isChecked = Util.getShowFenceSp() - cbDialogMapFencesSwitch.setOnCheckedChangeListener(mCheckedChangeListener) + cbDialogMapDashedLineSwitch.isChecked = + MMKVUtil.getBoolean(MMKVKey.ShowDashedLine, true) + cbDialogMapFencesSwitch.setOnCheckedChangeListener(mFenceCheckedChangeListener) + cbDialogMapDashedLineSwitch.setOnCheckedChangeListener(mDashedCheckedChangeListener) } } @@ -58,4 +65,8 @@ class SelectMapTypeDialog( fun setFencesSwitch(checked: Boolean) { mViewBinding.cbDialogMapFencesSwitch.isChecked = checked } + + fun setDashedSwitch(checked: Boolean) { + mViewBinding.cbDialogMapDashedLineSwitch.isChecked = checked + } } \ No newline at end of file diff --git a/app/src/main/java/com/abbidot/tracker/dialog/ShowCalenderAndTimeDialog.kt b/app/src/main/java/com/abbidot/tracker/dialog/ShowCalenderAndTimeDialog.kt index 6687a2f..84f2f50 100644 --- a/app/src/main/java/com/abbidot/tracker/dialog/ShowCalenderAndTimeDialog.kt +++ b/app/src/main/java/com/abbidot/tracker/dialog/ShowCalenderAndTimeDialog.kt @@ -21,6 +21,7 @@ import java.util.Calendar * @link * @description:显示日历弹窗 * @param canSelectFutureDate 平时正常日期,true不能选择未来时间 + * @param minLastDayRange 最小天数能选最近多少天,0表示没有限制 */ class ShowCalenderAndTimeDialog( context: Context, @@ -29,7 +30,8 @@ class ShowCalenderAndTimeDialog( format: String = Utils.DATE_FORMAT_PATTERN_EN1, canSelectFutureDate: Boolean = false, calenderShowTimestamp: Long = 0, - minYear: Int = 2023 + minYear: Int = 2023, + minLastDayRange: Int = 0 ) : BaseDialog( DialogCalenderAndTimeLayoutBinding::inflate, context ), OnValueChangeListener { @@ -44,7 +46,8 @@ class ShowCalenderAndTimeDialog( private val mOkListener = okListener private val mMinYear = minYear - private val mCalenderShowTimestamp = calenderShowTimestamp + private var mCalenderShowTimestamp = calenderShowTimestamp + private val mMinLastDayRange = minLastDayRange override fun initView() { mMonths = context.resources.getStringArray(R.array.array_month) @@ -58,7 +61,23 @@ class ShowCalenderAndTimeDialog( val cYear = calendar.get(Calendar.YEAR) val month = calendar.get(Calendar.MONTH) + 1 val day = calendar.get(Calendar.DAY_OF_MONTH) - it.setRange(mMinYear, 1, 1, cYear, month, day) + if (mMinLastDayRange > 0) { + val minTimestamp = Utils.getBeforeHowTimestamp( + calendar.timeInMillis, mMinLastDayRange.toLong() + ) + val minDate = + Utils.formatTime(minTimestamp, Utils.DATE_FORMAT_PATTERN_CN).split("-") + it.setRange( + minDate[0].toInt(), + minDate[1].toInt(), + minDate[2].toInt(), + cYear, + month, + day + ) + } else { + it.setRange(mMinYear, 1, 1, cYear, month, day) + } } updateMonthYear() @@ -104,8 +123,6 @@ class ShowCalenderAndTimeDialog( ) } - //根据传入的时间戳进行还原显示 - setSelectDate(mCalenderShowTimestamp) setOnClickListenerViews( llDialogCalenderLayout.ivSelectCalendarMonthLeft, @@ -117,6 +134,12 @@ class ShowCalenderAndTimeDialog( } } + override fun onStart() { + super.onStart() + //根据传入的时间戳进行还原显示 + setSelectDate(mCalenderShowTimestamp) + } + /** * 根据传入的时间戳进行还原显示 * @param showTimestamp 13位时间戳 @@ -174,11 +197,11 @@ class ShowCalenderAndTimeDialog( val nowTimestamp = System.currentTimeMillis() if (timesTamp > nowTimestamp) { - //时间戳还原 - setSelectDate(nowTimestamp) + mCalenderShowTimestamp = nowTimestamp mShowCalenderTextView.text = Utils.formatTime(nowTimestamp, mDateFormat) mOkListener?.onSelectClick(this@ShowCalenderAndTimeDialog, nowTimestamp) } else { + mCalenderShowTimestamp = timesTamp mShowCalenderTextView.text = Utils.stringToDate( selectMonthYear, Utils.DATE_FORMAT_PATTERN_CN2, mDateFormat ) diff --git a/app/src/main/java/com/abbidot/tracker/dialog/ShowCalenderDialog.kt b/app/src/main/java/com/abbidot/tracker/dialog/ShowCalenderDialog.kt index 3eecd83..cab25d8 100644 --- a/app/src/main/java/com/abbidot/tracker/dialog/ShowCalenderDialog.kt +++ b/app/src/main/java/com/abbidot/tracker/dialog/ShowCalenderDialog.kt @@ -100,7 +100,7 @@ class ShowCalenderDialog( * 根据传入的时间戳进行还原显示 * @param showTimestamp 13位时间戳 */ - fun setSelectDate(showTimestamp: Long) { + private fun setSelectDate(showTimestamp: Long) { if (showTimestamp > 0) { val calendar = java.util.Calendar.getInstance().apply { timeInMillis = showTimestamp diff --git a/app/src/main/java/com/abbidot/tracker/ui/activity/data/MoreActivityActivity.kt b/app/src/main/java/com/abbidot/tracker/ui/activity/data/MoreActivityActivity.kt index 6254d81..5780e56 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/activity/data/MoreActivityActivity.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/activity/data/MoreActivityActivity.kt @@ -324,7 +324,7 @@ class MoreActivityActivity : ) } } - }, calenderShowTimestamp = cTimestamp, minLastDayRange = 364) + }, calenderShowTimestamp = cTimestamp, minLastDayRange = 29) calenderDialog.show() } diff --git a/app/src/main/java/com/abbidot/tracker/ui/activity/data/MoreSleepActivity.kt b/app/src/main/java/com/abbidot/tracker/ui/activity/data/MoreSleepActivity.kt index 251ba99..332fd84 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/activity/data/MoreSleepActivity.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/activity/data/MoreSleepActivity.kt @@ -201,7 +201,7 @@ class MoreSleepActivity : ) } } - }, calenderShowTimestamp = cTimestamp, minLastDayRange = 364) + }, calenderShowTimestamp = cTimestamp, minLastDayRange = 29) calenderDialog.show() } diff --git a/app/src/main/java/com/abbidot/tracker/ui/activity/help/HelpCreatePetFenceActivity.kt b/app/src/main/java/com/abbidot/tracker/ui/activity/help/HelpCreatePetFenceActivity.kt index a07ee29..4e6c56e 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/activity/help/HelpCreatePetFenceActivity.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/activity/help/HelpCreatePetFenceActivity.kt @@ -25,24 +25,39 @@ class HelpCreatePetFenceActivity : ViewUtil.instance.addMenuBean( menuList, "", imageResId = R.drawable.create_fence_help1, menuType = MultipleEntity.IMG ) + ViewUtil.instance.addMenuBean( + menuList, getString(R.string.txt_set_fence_type) + ) + ViewUtil.instance.addMenuBean( + menuList, getString(R.string.txt_fence_type_help), menuType = MultipleEntity.IMG_IMG + ) + ViewUtil.instance.addMenuBean( + menuList, getString(R.string.txt_set_boundary) + ) ViewUtil.instance.addMenuBean( menuList, getString(R.string.txt_create_fence_tip2), menuType = MultipleEntity.IMG_IMG ) ViewUtil.instance.addMenuBean( menuList, "", imageResId = R.drawable.create_fence_help2, menuType = MultipleEntity.IMG ) + ViewUtil.instance.addMenuBean( + menuList, getString(R.string.txt_enable_set_notify) + ) ViewUtil.instance.addMenuBean( menuList, getString(R.string.txt_create_fence_tip3), menuType = MultipleEntity.IMG_IMG ) - ViewUtil.instance.addMenuBean( - menuList, "", imageResId = R.drawable.create_fence_help3, menuType = MultipleEntity.IMG - ) - ViewUtil.instance.addMenuBean( - menuList, getString(R.string.txt_create_fence_tip4), menuType = MultipleEntity.IMG_IMG - ) ViewUtil.instance.addMenuBean( menuList, "", imageResId = R.drawable.create_fence_help4, menuType = MultipleEntity.IMG ) + ViewUtil.instance.addMenuBean( + menuList, getString(R.string.txt_edit_delete_fence) + ) +// ViewUtil.instance.addMenuBean( +// menuList, getString(R.string.txt_create_fence_tip4), menuType = MultipleEntity.IMG_IMG +// ) +// ViewUtil.instance.addMenuBean( +// menuList, "", imageResId = R.drawable.create_fence_help4, menuType = MultipleEntity.IMG +// ) val helpCreateFenceAdapter = HelpTextImageTypeAdapter(menuList) ViewUtil.instance.setRecyclerViewVerticalLinearLayout( diff --git a/app/src/main/java/com/abbidot/tracker/ui/activity/help/HelpTrackerStatusActivity.kt b/app/src/main/java/com/abbidot/tracker/ui/activity/help/HelpTrackerStatusActivity.kt index c0c2111..608b4c4 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/activity/help/HelpTrackerStatusActivity.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/activity/help/HelpTrackerStatusActivity.kt @@ -1,18 +1,53 @@ package com.abbidot.tracker.ui.activity.help +import android.view.View import com.abbidot.tracker.R import com.abbidot.tracker.base.BaseActivity +import com.abbidot.tracker.constant.ConstantInt +import com.abbidot.tracker.constant.ConstantString import com.abbidot.tracker.databinding.ActivityHelpTrackerStatusBinding class HelpTrackerStatusActivity : BaseActivity(ActivityHelpTrackerStatusBinding::inflate) { + private var mType = ConstantInt.Type0 + override fun getTopBar() = mViewBinding.ilHelpTrackerStatusBar.titleTopBar override fun initData() { super.initData() - setTopBarTitle(R.string.txt_check_tracker_status) - setLeftBackImage(R.drawable.icon_white_back_svg) - mViewBinding.ilHelpTrackerStatusTitle1.tvHelpTitleOne.setText(R.string.txt_check_tracker_status_top_tip) + intent.extras?.apply { + mType = getInt(ConstantString.Type, ConstantInt.Type0) + } + mViewBinding.apply { + when (mType) { + 0 -> { + setTopBarTitle(R.string.txt_check_tracker_status) + setLeftBackImage(R.drawable.icon_white_back_svg) + ilHelpTrackerStatusTitle1.tvHelpTitleOne.setText(R.string.txt_check_tracker_status_top_tip) + } + + 1 -> { + setTopBarTitle(R.string.txt_sleep_mode) + setLeftBackImage(R.drawable.icon_white_back_svg) + ilHelpTrackerStatusTitle1.tvHelpTitleOne.setText(R.string.txt_sleep_mode_help) + ivHelpTrackerStatusImage.visibility = View.GONE + } + + 2 -> { + setTopBarTitle(R.string.txt_wifi_zone_home) + setLeftBackImage(R.drawable.icon_white_back_svg) + ilHelpTrackerStatusTitle1.tvHelpTitleOne.setText(R.string.txt_wifi_zone_home_help) + ivHelpTrackerStatusImage.visibility = View.GONE + } + + 3 -> { + setTopBarTitle(R.string.tracker_manage_set_duration) + setLeftBackImage(R.drawable.icon_white_back_svg) + ilHelpTrackerStatusTitle1.tvHelpTitleOne.setText(R.string.txt_gps_update_help) + ivHelpTrackerStatusImage.visibility = View.GONE + } + } + } } } \ No newline at end of file diff --git a/app/src/main/java/com/abbidot/tracker/ui/activity/help/HowWorkActivity.kt b/app/src/main/java/com/abbidot/tracker/ui/activity/help/HowWorkActivity.kt index 0120b48..4155402 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/activity/help/HowWorkActivity.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/activity/help/HowWorkActivity.kt @@ -7,6 +7,8 @@ import com.abbidot.tracker.R import com.abbidot.tracker.adapter.HowWorkAdapter import com.abbidot.tracker.base.BaseActivity import com.abbidot.tracker.bean.MenuTxtBean +import com.abbidot.tracker.constant.ConstantInt +import com.abbidot.tracker.constant.ConstantString import com.abbidot.tracker.databinding.ActivityHowWorkBinding import com.abbidot.tracker.util.ViewUtil import com.qmuiteam.qmui.util.QMUIDisplayHelper @@ -26,7 +28,10 @@ class HowWorkActivity : BaseActivity(ActivityHowWorkBind ViewUtil.instance.addMenuBean(menuList, getString(R.string.txt_power_on_off)) ViewUtil.instance.addMenuBean(menuList, getString(R.string.txt_active_tracker)) ViewUtil.instance.addMenuBean(menuList, getString(R.string.txt_check_tracker_status)) - ViewUtil.instance.addMenuBean(menuList, getString(R.string.txt_tracker_battery_life)) + ViewUtil.instance.addMenuBean(menuList, getString(R.string.txt_sleep_mode)) + ViewUtil.instance.addMenuBean(menuList, getString(R.string.txt_wifi_zone_home)) + ViewUtil.instance.addMenuBean(menuList, getString(R.string.tracker_manage_set_duration)) +// ViewUtil.instance.addMenuBean(menuList, getString(R.string.txt_tracker_battery_life)) ViewUtil.instance.addMenuBean(menuList, getString(R.string.txt_create_pet_fence)) mHowWorkAdapter = HowWorkAdapter(this, menuList).apply { setOnItemClickListener(object : BaseRecyclerAdapter.OnItemClickListener { @@ -35,8 +40,26 @@ class HowWorkActivity : BaseActivity(ActivityHowWorkBind 0 -> startActivity(Intent(mContext, HelpPowerOnOffActivity::class.java)) 1 -> startActivity(Intent(mContext, HelpActiveTrackerActivity::class.java)) 2 -> startActivity(Intent(mContext, HelpTrackerStatusActivity::class.java)) - 3 -> startActivity(Intent(mContext, HelpTrackerBatteryActivity::class.java)) - 4 -> startActivity(Intent(mContext, HelpCreatePetFenceActivity::class.java)) + 3 -> { + Intent(mContext, HelpTrackerStatusActivity::class.java).let { + it.putExtra(ConstantString.Type, ConstantInt.Type1) + startActivity(it) + } + } + 4 -> { + Intent(mContext, HelpTrackerStatusActivity::class.java).let { + it.putExtra(ConstantString.Type, ConstantInt.Type2) + startActivity(it) + } + } + 5 -> { + Intent(mContext, HelpTrackerStatusActivity::class.java).let { + it.putExtra(ConstantString.Type, ConstantInt.Type3) + startActivity(it) + } + } + + 6 -> startActivity(Intent(mContext, HelpCreatePetFenceActivity::class.java)) } } }) 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 44d8a1a..6807c51 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 @@ -91,6 +91,9 @@ class LiveActivityV3 : BaseActivity(ActivityLiveV3Binding //是否显示围栏 private var isShowFence = true + //是否显示虚线 + private var isShowDashed = true + //地图类型,标准和卫星地图 private var mMapType = ConstantInt.Type0 private var mShowCenterLocation = ConstantInt.PetLocationType @@ -138,6 +141,7 @@ class LiveActivityV3 : BaseActivity(ActivityLiveV3Binding } isShowFence = Util.getShowFenceSp() + isShowDashed = MMKVUtil.getBoolean(MMKVKey.ShowDashedLine, true) mViewBinding.apply { ViewUtil.instance.viewRotationAnimator( @@ -775,7 +779,8 @@ class LiveActivityV3 : BaseActivity(ActivityLiveV3Binding private fun showMapTypeDialog() { if (null == mSelectMapTypeDialog) { mSelectMapTypeDialog = ViewUtil.instance.getMapTypeDialog( - mContext, object : BaseRecyclerAdapter.OnItemClickListener { + mContext, + object : BaseRecyclerAdapter.OnItemClickListener { override fun onItemClick(itemView: View?, pos: Int) { mMapType = Util.getMapTypeSp() if (pos == mMapType) { @@ -783,8 +788,8 @@ class LiveActivityV3 : BaseActivity(ActivityLiveV3Binding } mHomeMapCommon.switchSatelliteAndNormalMapType() } - }) { v, isChecked -> - if (v.id == R.id.cb_dialog_map_fences_switch) { + }, + { _, isChecked -> isShowFence = isChecked MMKVUtil.putBoolean(MMKVKey.ShowFence, isChecked) if (isChecked) { @@ -794,8 +799,16 @@ class LiveActivityV3 : BaseActivity(ActivityLiveV3Binding } else { mFencesMapViewModel.setFencesData(mContext, null, mFragment) } - } - } + }, + { _, isChecked -> + isShowDashed = isChecked + MMKVUtil.putBoolean(MMKVKey.ShowDashedLine, isChecked) + if (isChecked) { + mHomeMapCommon.addUserAndPetLine() + } else { + mHomeMapCommon.removeUserAndPetLine() + } + }) } else { mSelectMapTypeDialog!!.mapTypeSpToUpdate() } @@ -990,6 +1003,9 @@ class LiveActivityV3 : BaseActivity(ActivityLiveV3Binding } } } + if (isShowDashed) { + mHomeMapCommon.addUserAndPetLine() + } } } } diff --git a/app/src/main/java/com/abbidot/tracker/ui/activity/subscribe/SureSubscriptionPlanActivity.kt b/app/src/main/java/com/abbidot/tracker/ui/activity/subscribe/SureSubscriptionPlanActivity.kt index 2635a73..c5f4303 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/activity/subscribe/SureSubscriptionPlanActivity.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/activity/subscribe/SureSubscriptionPlanActivity.kt @@ -62,6 +62,7 @@ class SureSubscriptionPlanActivity : //升级套餐还剩下多少差价 private var mResidualMoney = 0.0 + //设备类型 private var mType = ConstantInt.Type1 @@ -253,7 +254,7 @@ class SureSubscriptionPlanActivity : ViewUtil.instance.addMenuBean( mSummaryAdapter.getData(), p.planName, - "$price", + Utils.formatDecimal(p.planPrice, 2), colorRedId = R.color.data_black_color ) mTotalMoney += price @@ -289,12 +290,12 @@ class SureSubscriptionPlanActivity : isSwitch = true ) } - ViewUtil.instance.addMenuBean( - mSummaryAdapter.getData(), - getString(R.string.txt_sales_tax), - "0", - colorRedId = R.color.data_black_color - ) +// ViewUtil.instance.addMenuBean( +// mSummaryAdapter.getData(), +// getString(R.string.txt_sales_tax), +// "0", +// colorRedId = R.color.data_black_color +// ) } //判断套餐是否过期 或者套餐没退款 @@ -417,9 +418,10 @@ class SureSubscriptionPlanActivity : private fun updateMoney() { mViewBinding.apply { val list = mSummaryAdapter.getData() - val taxMoney = abs(Utils.formatDecimal(mTaxRate * mTotalMoney, 2).toDouble()) +// val taxMoney = abs(Utils.formatDecimal(mTaxRate * mTotalMoney, 2).toDouble()) + val taxMoney = 0.0 mOrderBean?.tax = taxMoney - list[list.size - 1].menuValue = taxMoney.toString() +// list[list.size - 1].menuValue = taxMoney.toString() mTotalWithTaxMoney = taxMoney + mTotalMoney mTotalWithTaxMoney = abs(mTotalWithTaxMoney) ilSubscribePlanSummary.ilSureSubscribePlanTotalLayout.tvSubscribeSummaryItemMoney.text = 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 index 1631715..fcf1c14 100644 --- 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 @@ -10,7 +10,6 @@ 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.constant.LinkMapCallback import com.abbidot.tracker.databinding.LayoutPetLocationInfoBinding import com.abbidot.tracker.ui.fragment.map.baidumap.HomeMapBaiduMapFragment import com.abbidot.tracker.ui.fragment.map.googlemap.HomeMapGoogleMapFragmentV3 @@ -199,6 +198,14 @@ class HomeMapCommonV3 @Inject constructor() : BaseMapCommon() { return mHomeMapGoogleMapFragment?.mUserLatLng } + fun addUserAndPetLine() { + mHomeMapGoogleMapFragment?.addUserAndPetLine() + } + + fun removeUserAndPetLine() { + mHomeMapGoogleMapFragment?.removeUserAndPetLine() + } + // fun getAddressShowMarkerInfoWindow(historyDataBean: HistoryDataBean) { // if (null != mHomeMapBaiduMapFragment) { // mHomeMapBaiduMapFragment!!.showMarkerInfoWindow(historyDataBean) diff --git a/app/src/main/java/com/abbidot/tracker/ui/fragment/data/RouteV3Fragment.kt b/app/src/main/java/com/abbidot/tracker/ui/fragment/data/RouteV3Fragment.kt index 798b14e..23e88ee 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/fragment/data/RouteV3Fragment.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/fragment/data/RouteV3Fragment.kt @@ -643,7 +643,8 @@ class RouteV3Fragment : BaseFragment(FragmentRouteV3Bind } }, calenderShowTimestamp = mFromTimestamp, - format = Utils.DATE_FORMAT_PATTERN_EN13 + format = Utils.DATE_FORMAT_PATTERN_EN13, + minLastDayRange = 29 ) } mFromCalenderDialog?.show() @@ -672,7 +673,8 @@ class RouteV3Fragment : BaseFragment(FragmentRouteV3Bind } }, calenderShowTimestamp = mToTimestamp, - format = Utils.DATE_FORMAT_PATTERN_EN13 + format = Utils.DATE_FORMAT_PATTERN_EN13, + minLastDayRange = 29 ) } mToCalenderDialog?.show() diff --git a/app/src/main/java/com/abbidot/tracker/ui/fragment/device/HomeTrackFragment.kt b/app/src/main/java/com/abbidot/tracker/ui/fragment/device/HomeTrackFragment.kt index ef5ede9..844605c 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/fragment/device/HomeTrackFragment.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/fragment/device/HomeTrackFragment.kt @@ -503,7 +503,7 @@ class HomeTrackFragment : ViewUtil.instance.addMenuBean( mTrackStateList, getString(R.string.tracker_manage_set_gps), - getString(R.string.tracker_manage_set_led_off), + getString(R.string.txt_sleep), imageResId = R.drawable.icon_map_gps ) ViewUtil.instance.addMenuBean( @@ -669,7 +669,7 @@ class HomeTrackFragment : it.menuValue = if (isTimeoutReport || powerSwitch == ConstantInt.Type0 || powerSwitch == ConstantInt.Type2 || powerSwitch == ConstantInt.Type3 || inWifiZone == ConstantInt.Type1) { it.colorRedId = R.color.orange_color3 - getString(R.string.tracker_manage_set_led_off) + getString(R.string.txt_sleep) } else if (gpsSignal > ConstantInt.WeakSignal) getString(R.string.txt_strong_signal) else if (gpsSignal == ConstantInt.NoSignal) { it.colorRedId = R.color.orange_color3 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 029a22c..1c43062 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 @@ -9,6 +9,8 @@ import android.location.LocationManager import android.provider.Settings import android.view.Gravity import android.view.View +import android.widget.CompoundButton +import android.widget.CompoundButton.OnCheckedChangeListener import androidx.activity.result.contract.ActivityResultContracts import androidx.core.content.ContextCompat import androidx.core.view.WindowInsetsCompat @@ -63,7 +65,8 @@ import javax.inject.Inject * create an instance of this fragment. */ @AndroidEntryPoint -class MapV3Fragment : BaseFragment(FragmentMapV3Binding::inflate) { +class MapV3Fragment : BaseFragment(FragmentMapV3Binding::inflate), + OnCheckedChangeListener { private val mFencesMapViewModel: FencesMapViewModel by viewModels() private val mMapViewModel: MapViewModel by viewModels() @@ -93,6 +96,9 @@ class MapV3Fragment : BaseFragment(FragmentMapV3Binding::i //是否显示围栏 private var isShowFence = true + //是否显示虚线 + private var isShowDashed = true + //地图类型,标准和卫星地图 private var mMapType = ConstantInt.Type0 @@ -120,6 +126,7 @@ class MapV3Fragment : BaseFragment(FragmentMapV3Binding::i } isShowFence = Util.getShowFenceSp() + isShowDashed = MMKVUtil.getBoolean(MMKVKey.ShowDashedLine, true) mViewBinding.apply { getHomeV2Activity()?.edgeToEdgeAdapterBars( @@ -208,6 +215,7 @@ class MapV3Fragment : BaseFragment(FragmentMapV3Binding::i } val showFence = Util.getShowFenceSp() + val showDashed = MMKVUtil.getBoolean(MMKVKey.ShowDashedLine, true) //检测直播页面有没有修改围栏显示 if (isShowFence != showFence) { if (null == mSelectMapTypeDialog) { @@ -216,6 +224,13 @@ class MapV3Fragment : BaseFragment(FragmentMapV3Binding::i mSelectMapTypeDialog?.setFencesSwitch(showFence) } } + if (isShowDashed != showDashed) { + if (null == mSelectMapTypeDialog) { + setDashedShow(showDashed) + } else { + mSelectMapTypeDialog?.setDashedSwitch(showDashed) + } + } } private fun getHomeV2Activity(): HomeV2Activity? { @@ -548,11 +563,8 @@ class MapV3Fragment : BaseFragment(FragmentMapV3Binding::i } mHomeMapCommon.switchSatelliteAndNormalMapType() } - }) { v, isChecked -> - if (v.id == R.id.cb_dialog_map_fences_switch) { - setFencesShow(isChecked) - } - } + }, this, this + ) else { mSelectMapTypeDialog!!.mapTypeSpToUpdate() } @@ -574,6 +586,19 @@ class MapV3Fragment : BaseFragment(FragmentMapV3Binding::i } } + /** + * 设置虚线显示 + */ + private fun setDashedShow(isShow: Boolean) { + isShowDashed = isShow + MMKVUtil.putBoolean(MMKVKey.ShowDashedLine, isShow) + if (isShow) { + mHomeMapCommon.addUserAndPetLine() + } else { + mHomeMapCommon.removeUserAndPetLine() + } + } + /** * 设置需要更新的标识 */ @@ -678,6 +703,9 @@ class MapV3Fragment : BaseFragment(FragmentMapV3Binding::i mFencesMapViewModel.setFencesData(mContext!!, fences, mFragment) } } + if (isShowDashed) { + mHomeMapCommon.addUserAndPetLine() + } } } @@ -929,6 +957,12 @@ class MapV3Fragment : BaseFragment(FragmentMapV3Binding::i // } // } + override fun onCheckedChanged(v: CompoundButton, isChecked: Boolean) { + when (v.id) { + R.id.cb_dialog_map_fences_switch -> setFencesShow(isChecked) + R.id.cb_dialog_map_dashed_line_switch -> setDashedShow(isChecked) + } + } override fun onClick(v: View?) { mViewBinding.apply { @@ -1008,5 +1042,4 @@ class MapV3Fragment : BaseFragment(FragmentMapV3Binding::i } } } - } \ No newline at end of file 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 f51ff9f..6edf02a 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 @@ -406,14 +406,15 @@ abstract class BaseGoogleMapFragment : if (MMKVUtil.getBoolean(MMKVKey.isGpsToGCJ02)) { mUserLatLng?.let { if (null == mUserMarker) { - mUserMarker = addImageMarker(it, R.drawable.icon_user_location_image) + mUserMarker = addImageMarker(it, R.drawable.icon_user_location_image,false) } else { if (it.latitude == mUserMarker!!.position.latitude && it.longitude == mUserMarker!!.position.longitude) { } else { mUserMarker?.remove() - mUserMarker = addImageMarker(it, R.drawable.icon_user_location_image) + mUserMarker = addImageMarker(it, R.drawable.icon_user_location_image,false) } } + mUserMarker?.setAnchor(0.5f,0.5f) } } // else { @@ -791,7 +792,7 @@ abstract class BaseGoogleMapFragment : /** * 获取地图画线的PolylineOptions */ - private fun getPolylineOptions(widthDp: Float, lineColorRes: Int): PolylineOptions { + fun getPolylineOptions(widthDp: Float, lineColorRes: Int): PolylineOptions { return PolylineOptions().clickable(false).width(AppUtils.dpToPx(widthDp)) .color(ContextCompat.getColor(mContext!!, lineColorRes)).geodesic(false) } 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 index a4f97a3..178ca15 100644 --- 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 @@ -25,7 +25,6 @@ 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 /** @@ -47,7 +46,7 @@ class HomeMapGoogleMapFragmentV3 : BaseGoogleMapFragment() { //启动动画移动地图摄像机 private var isMoveCamera = true - private var mPolyline: Polyline? = null + private var mUserAndPetLine: Polyline? = null private var mRippleCircle: Circle? = null private var mValueAnimator: ValueAnimator? = null @@ -111,6 +110,19 @@ class HomeMapGoogleMapFragmentV3 : BaseGoogleMapFragment() { mPetLocationLayoutBinding.let { layout -> layout.tvPetLocationReverseGeocode.text = address layout.tvPetLocationUpdateTime.text = timeString + layout.tvPetLocationUpdateTimeFormat.visibility = + if (powerSwitch == ConstantInt.Type2) View.GONE + else { + if (Util.isTimeoutReport(updateTime, gnssInterval)) { + layout.tvPetLocationUpdateTimeFormat.text = String.format( + getString(R.string.txt_location_ago), + Utils.getTimeDifference( + updateTime * 1000, System.currentTimeMillis() + ) + ) + View.VISIBLE + } else View.GONE + } } } } @@ -207,27 +219,26 @@ class HomeMapGoogleMapFragmentV3 : BaseGoogleMapFragment() { /** * 画用户和宠物之间的虚线 */ - 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 + fun addUserAndPetLine() { + mGoogleMap?.apply { + mUserLatLng?.let { u -> + mPetLatLng?.let { p -> + mUserAndPetLine?.remove() + getPolylineOptions(1.5f, R.color.blue_color9).let { + it.add(toGCJ02LatLon(p)) + it.add(toGCJ02LatLon(u)) + mUserAndPetLine = addPolyline(it) + } + mUserAndPetLine?.pattern = getDashedPatternStyle(18f) } } } } + fun removeUserAndPetLine() { + mUserAndPetLine?.remove() + } + /** * 初始化并添加水波纹圆 */ 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 8a31494..bcf24e6 100644 --- a/app/src/main/java/com/abbidot/tracker/util/ViewUtil.kt +++ b/app/src/main/java/com/abbidot/tracker/util/ViewUtil.kt @@ -878,7 +878,8 @@ class ViewUtil private constructor() { fun getMapTypeDialog( context: Context, onItemClickListener: BaseRecyclerAdapter.OnItemClickListener? = null, - checkedChangeListener: CompoundButton.OnCheckedChangeListener? = null + fenceCheckedChangeListener: CompoundButton.OnCheckedChangeListener? = null, + dashedCheckedChangeListener: CompoundButton.OnCheckedChangeListener? = null ): SelectMapTypeDialog { val mapType = Util.getMapTypeSp() val typeList = mutableListOf() @@ -902,7 +903,9 @@ class ViewUtil private constructor() { } }) } - return SelectMapTypeDialog(context, mapTypeAdapter, checkedChangeListener) + return SelectMapTypeDialog( + context, mapTypeAdapter, fenceCheckedChangeListener, dashedCheckedChangeListener + ) } /** 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 7103eb4..1f6ac7a 100644 --- a/app/src/main/java/com/abbidot/tracker/vm/MapViewModel.kt +++ b/app/src/main/java/com/abbidot/tracker/vm/MapViewModel.kt @@ -35,7 +35,6 @@ import com.abbidot.tracker.widget.TypefaceButton import com.abbidot.tracker.widget.TypefaceTextView import com.clj.fastble.BleManager import kotlinx.coroutines.launch -import java.util.concurrent.TimeUnit class MapViewModel : ViewModel() { @@ -114,7 +113,7 @@ class MapViewModel : ViewModel() { menuType = ConstantInt.Close name = context.getString(R.string.tracker_manage_set_gps) value = - context.getString(R.string.tracker_manage_set_gps) + ":" + context.getString(R.string.tracker_manage_set_led_off) + context.getString(R.string.tracker_manage_set_gps) + ":" + context.getString(R.string.txt_sleep) deviceStateList.add(this) } DataBean().apply { @@ -302,7 +301,7 @@ class MapViewModel : ViewModel() { deviceStateList[1].apply { menuType = ConstantInt.Close value = - context.getString(R.string.tracker_manage_set_gps) + ":" + context.getString(R.string.tracker_manage_set_led_off) + context.getString(R.string.tracker_manage_set_gps) + ":" + context.getString(R.string.txt_sleep) } deviceStateList[2].apply { menuType = ConstantInt.Close @@ -344,13 +343,12 @@ class MapViewModel : ViewModel() { val gpsValue = 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) + context.getString(R.string.txt_sleep) } else if (it.gpsSignal > ConstantInt.WeakSignal) context.getString(R.string.txt_strong_signal) else if (it.gpsSignal == ConstantInt.NoSignal) { menuType = ConstantInt.Close context.getString(R.string.txt_no_signal) - } - else context.getString(R.string.txt_weak_signal) + } else context.getString(R.string.txt_weak_signal) value = context.getString(R.string.tracker_manage_set_gps) + ":$gpsValue" } deviceStateList[2].apply { @@ -476,7 +474,7 @@ class MapViewModel : ViewModel() { ) it.text = String.format( context.getString(R.string.txt_fell_asleep), - getTimeDifference(updateTime * 1000, System.currentTimeMillis()) + Utils.getTimeDifference(updateTime * 1000, System.currentTimeMillis()) ) ViewUtil.instance.viewShow(closeBtn) } else if (powerSwitch == ConstantInt.Type0) { @@ -517,37 +515,6 @@ class MapViewModel : ViewModel() { } } - private fun getTimeDifference(startMillis: Long, endMillis: Long): String { - var diff = endMillis - startMillis - val days = TimeUnit.MILLISECONDS.toDays(diff) - diff -= TimeUnit.DAYS.toMillis(days) - - val hours = TimeUnit.MILLISECONDS.toHours(diff) - diff -= TimeUnit.HOURS.toMillis(hours) - - val minutes = TimeUnit.MILLISECONDS.toMinutes(diff) - var timeStr: String - if (days > 0) { - timeStr = if (days > 1) { - "$days days" - } else { - "$days day" - } - if (hours > 0) { - timeStr += " ${hours}h" - } - } else { - if (hours > 0) { - timeStr = "${hours}h" - if (minutes > 0) timeStr += " ${minutes}m" - } else { - timeStr = if (minutes > 0) "${minutes}m" - else "1m" - } - } - return timeStr - } - fun setPetLocationReverseGeocode( context: Context, mapDeviceBean: MapDeviceBean, diff --git a/app/src/main/java/com/abbidot/tracker/widget/calender/HorizontalCalenderViewV2.java b/app/src/main/java/com/abbidot/tracker/widget/calender/HorizontalCalenderViewV2.java index 7dbf740..5c12e93 100644 --- a/app/src/main/java/com/abbidot/tracker/widget/calender/HorizontalCalenderViewV2.java +++ b/app/src/main/java/com/abbidot/tracker/widget/calender/HorizontalCalenderViewV2.java @@ -159,7 +159,8 @@ public class HorizontalCalenderViewV2 extends FrameLayout { //获取当月的日期 // List items = getItems(); //获取最近365天的日期 - List items = getLast365DaysItems(); + // List items = getLast365DaysItems(); + List items = getLast30DaysItems(); adapter = new DayV2Adapter(context, items, dayTextColorSelected, dayTextColorNormal, daySelectionColor, weekTextColor, pressShapeSelectorId, todayPointColor); adapter.setItemClick((year, month, day, week) -> { diff --git a/app/src/main/res/layout/activity_help_power_on_off.xml b/app/src/main/res/layout/activity_help_power_on_off.xml index a36aa50..2c39994 100644 --- a/app/src/main/res/layout/activity_help_power_on_off.xml +++ b/app/src/main/res/layout/activity_help_power_on_off.xml @@ -1,5 +1,6 @@ + + android:layout_marginHorizontal="@dimen/dp_22" + android:layout_marginTop="@dimen/dp_6" /> + + + android:layout_marginTop="@dimen/dp_6" + android:layout_marginBottom="@dimen/dp_26" /> + android:layout_marginTop="@dimen/dp_20" + android:visibility="gone" /> + @@ -58,12 +58,14 @@ style="@style/my_TextView_style_v2" android:layout_weight="1" android:gravity="start" - android:text="@string/txt_show_accuracy" + android:text="@string/txt_display_dashed_line" android:textSize="@dimen/textSize14" app:typeface="@string/roboto_bold_font" /> + android:layout_width="@dimen/dp_47" + android:checked="true" /> \ No newline at end of file diff --git a/app/src/main/res/layout/item_subscribe_summary_layout.xml b/app/src/main/res/layout/item_subscribe_summary_layout.xml index 22ab74f..a13505a 100644 --- a/app/src/main/res/layout/item_subscribe_summary_layout.xml +++ b/app/src/main/res/layout/item_subscribe_summary_layout.xml @@ -10,7 +10,7 @@ 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 41295a2..60aa6a0 100644 --- a/app/src/main/res/layout/layout_pet_location_info.xml +++ b/app/src/main/res/layout/layout_pet_location_info.xml @@ -30,6 +30,15 @@ android:textSize="@dimen/textSize12" app:typeface="@string/roboto_regular_font" /> + + Ziehen zum Laden weiterer Inhalte Loslassen zum Laden Voll aufgeladen - Vor %@ eingeschlafen - Bewegen Sie %@ zum Aufwecken + Vor %s eingeschlafen + Bewegen Sie %s zum Aufwecken Zeitleiste Halten Sie das Telefon nah ans Gerät Auto-Verlängerung: Kündigen @@ -979,5 +979,14 @@ espeichert. Aktiv, wenn online. Verlängerung: $%s / %s Jahre am %s Verlängerung: $%s / %s Monate am %s + Die Rückerstattungsfrist ist abgelaufen + Rückerstattungsrichtlinie\n + Automatische Rückerstattung (innerhalb von 48 Stunden) + Alle Abonnementkäufe sind innerhalb von 48 Stunden nach Zahlung für eine vollständige automatische Rückerstattung berechtigt. Die Rückerstattungen werden automatisch ohne manuelle Prüfung bearbeitet.\n + Standard-Rückerstattungszeitraum (30 Tage) + Nach der ersten 48-Stunden-Frist können Benutzer innerhalb von 30 Tagen nach dem Kauf eine Rückerstattung beantragen.\n\t1. Alle Abonnementpläne (3 Monate, 1 Jahr, 2 Jahre) sind berechtigt\n\t2. Rückerstattungsanträge unterliegen der Prüfung und Genehmigung\n\t3. Rückerstattungen können je nach Nutzung und Serviceverbrauch teilweise angepasst werden\n + Abonnements, die älter als 30 Tage sind, können nicht erstattet werden. + Keine Rückerstattung nach 30 Tagen + Gestrichelte Linie anzeigen \ 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 1b4f24f..ef67747 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -1023,5 +1023,14 @@ 已保存,上线时生效。 续订:$%s / %s 年,于 %s 续订:$%s / %s 月,于 %s + 退款期限已过 + 退款政策\n + 自动退款(48小时内) + 所有订阅购买在付款后48小时内均可享受全额自动退款。退款将自动处理,无需人工审核。\n + 标准退款窗口(30天) + 在最初的48小时之后,用户可在购买后30天内申请退款。\n\t1. 所有订阅计划(3个月、1年、2年)均符合条件\n\t2. 退款申请需经过审核和批准\n\t3. 退款可能会根据使用情况和服务消耗进行部分调整\n + 超过30天的订阅不可退款。 + 30天后不退款 + 显示虚线 \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 8d011d5..7a6356a 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -379,4 +379,5 @@ #F9FFE8 #B0B0B0 #758E94 + #FF996E \ 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 d58ba44..a59661c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -847,8 +847,8 @@ Reminder Yesterday Power On/Off - Fully charge the tracker, then remove the cable. When the green light flashes, the tracker is powered on. - Select and complete your subscription, then click to activate the tracker on the app. Once activated, the tracker can be used for GPS tracking and cellular network connectivity. + Charge and unplug to turn on Flashing green light = on + Choose a subscription Tap to activate the tracker Enable GPS and cellular tracking Active Tracker (The GPS and cellular network conditions can vary depending on the environment. Before placing it on your pet, check various locations around you to evaluate the GPS and network status.) Check Tracker Status @@ -859,11 +859,11 @@ (Shorter network intervals drain the Tracker\'s battery faster. By default, the network reconnects every 15 minutes.) When Live mode is activated, the Tracker enters a rapid positioning and networking state, usually within 15–20 seconds. This mode drains the battery the quickest, so it\'s best reserved for emergency situations. Tracker Battery Life - 1.Fence Settings: Select "Pet" > "My Pet Fence". Click "Manage" > "+ Add new" to create or edit a fence for Safe Zone or No-go Zone. - 2.Define Boundary: Choose a location on the map, adjust the fence\'s radius or shape. - 3.Save Settings: Save to activate the geofence. + Go to Pet > My Pet Fence > Manage > + Add New + Choose location and adjust radius or shapeSave fence to activate it + Alerts when pet enters or leaves the zone 4.Turn on Notifications: Go to \'Account\' > \'Settings\'. Click \'Notifications\' and turn on - Creating My Pet Fence + Create a Pet Fence Tracker in Sleeping Mode (Super Low power usage) Tracker in WiFi Zone @@ -1010,8 +1010,8 @@ Sure to delete this card? 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. + Shake to turn on Flashing green light confirms on + Go to Pet > Tracker Check Network GPS Battery WiFi Zone Bluetooth LED GPS and cellular signals may vary by location Test in different locations before use Tracker is on charging Subscribed Send @@ -1090,5 +1090,20 @@ After the initial 48-hour period, users may request a refund within 30 days of purchase.\n\t1.All subscription plans (3-Month, 1-Year, 2-Year) are eligible\n\t2.Refund requests are subject to review and approval\n\t3.Refunds may be partially adjusted based on usage and service consumption\n Subscriptions older than 30 days are non-refundable. No Refund After 30 Days + Display Dashed Line + First use + Daily use + Sleep Mode + 15 minutes no movement → sleep mode Auto wake on movement Battery updates every 24 hours + WiFi Zone(Home) + Connect to home WiFi GPS off → save battery Update every ~60 minutes + Pet > Tracker > GPS Update Select 3–15 min Short interval = higher battery use Default: 5 min + Set Fence type + Safe Zone or No-go Zone + Set boundary + Enable alerts in Account > Settings > Notifications + Edit or delete fence in Manage + Total + (%s ago) \ No newline at end of file diff --git a/baselibrary/src/main/java/com/abbidot/baselibrary/constant/MMKVKey.kt b/baselibrary/src/main/java/com/abbidot/baselibrary/constant/MMKVKey.kt index 8ed2af3..d62049a 100644 --- a/baselibrary/src/main/java/com/abbidot/baselibrary/constant/MMKVKey.kt +++ b/baselibrary/src/main/java/com/abbidot/baselibrary/constant/MMKVKey.kt @@ -37,6 +37,7 @@ import androidx.annotation.StringDef MMKVKey.isGpsToGCJ02, MMKVKey.MapType, MMKVKey.ShowFence, + MMKVKey.ShowDashedLine, MMKVKey.isCrash, MMKVKey.AvailableOrder, MMKVKey.isFirstCheckBleOpen, @@ -92,6 +93,7 @@ annotation class MMKVKey { //map页是否显示围栏 const val ShowFence = "isShowFence" + const val ShowDashedLine = "isShowDashedLine" //是首次打开APP const val FirstOpen = "firstOpen" 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 d144311..8677e27 100644 --- a/baselibrary/src/main/java/com/abbidot/baselibrary/util/Utils.kt +++ b/baselibrary/src/main/java/com/abbidot/baselibrary/util/Utils.kt @@ -11,6 +11,7 @@ import java.util.Calendar import java.util.Date import java.util.Locale import java.util.TimeZone +import java.util.concurrent.TimeUnit import java.util.regex.Pattern import kotlin.math.atan2 import kotlin.math.cos @@ -217,6 +218,40 @@ class Utils { return "${fill2Digits(hour)}:${fill2Digits(minutes)}:${fill2Digits(second)}" } + /** + * 格式化2个时间相差多少 + */ + fun getTimeDifference(startMillis: Long, endMillis: Long): String { + var diff = endMillis - startMillis + val days = TimeUnit.MILLISECONDS.toDays(diff) + diff -= TimeUnit.DAYS.toMillis(days) + + val hours = TimeUnit.MILLISECONDS.toHours(diff) + diff -= TimeUnit.HOURS.toMillis(hours) + + val minutes = TimeUnit.MILLISECONDS.toMinutes(diff) + var timeStr: String + if (days > 0) { + timeStr = if (days > 1) { + "$days days" + } else { + "$days day" + } + if (hours > 0) { + timeStr += " ${hours}h" + } + } else { + if (hours > 0) { + timeStr = "${hours}h" + if (minutes > 0) timeStr += " ${minutes}m" + } else { + timeStr = if (minutes > 0) "${minutes}m" + else "1m" + } + } + return timeStr + } + /** * 把秒转换为 day hour min */