Compare commits

...

19 Commits

Author SHA1 Message Date
yezhiqiu
46c0a5b2a4 1. wifi zone定位点设置,改为拖动地图设置
2.添加被绑定设备增加提示被绑定的邮箱
2026-05-11 17:04:05 +08:00
yezhiqiu
0654ec87bc 1.修复位置滞后时间与上报时间重叠问题
2.宠物名称限制字数-限制为16个字符长度(中文为8个字)
3.优化添加和编辑wifi,按钮操作过程中禁止点击其他按钮
4.优化运动超过运动目标后,显示指定的百分比,取消最大值为100%
5.优化宠物和手机位置直线虚线默认显示改为默认不显示
6.修复打开邀请家人页面,切换到其它应用再切换回来,左上角返回按钮错位问题
2026-05-11 09:53:49 +08:00
yezhiqiu
5be446af72 1.map和直播页增加用户和宠物虚线设置
2.优化帮助页面
3.支付页面去掉税的计算
4.GPS: Off 改为GPS: Sleep;
5.map页增加位置更新时间格式:当更新滞后超过2倍的上报间隔时,才显示
(2h 35m ago)”,显示休眠中时,不显示“(2h 35m ago)
6.运动数据改为查看30天数据
7.历史轨迹限制只能看30天数据
2026-05-07 12:02:55 +08:00
yezhiqiu
587697954d 1.修复充电中,Map 显示Off, 但设备管理中显示Strong signal bug
2.修复GPS 没信号还是为绿点bug
3.超过30天后,退款按钮呈灰色不可点,点击后提示“Refund period has expired”,续订订单不显示按钮
4.历史订单列表页,增加退款说明
2026-04-29 10:27:29 +08:00
yezhiqiu
8d1a44bf89 1.优化区分信号弱/无信号(4种状态:1. wifi zone 中/关机/休眠/充电/超时无上报-关,2. 信号大于50-强,信号大于0小于50 -弱,3. 信号等于0-无)
2.修复围栏编辑和添加保存时/删除时,还可以输入内容和点‘取消’按钮
3.修复删除围栏时,还可以点击编辑按钮
4.修复轨迹页面围栏名字太长,列表对不齐
5.修复轨迹只有3个点时,滑块滑不动的bug
6.修复直播页面第三个导航无法点击bug
7.校对多语言字符
2026-04-24 18:55:38 +08:00
yezhiqiu
505a0414b8 适配部分机型还会出现输入框被键盘挡住问题 2026-04-24 10:29:15 +08:00
yezhiqiu
fa5b707c22 1.在解绑提示页面,增加提示语“Auto-Renew: Cancel”
2.适配Google Play 要求支持 16 KB 的内存页面大小,更新大部分第三方库到最新版本
2026-04-21 18:00:06 +08:00
yezhiqiu
4547f844ba 1.在解绑提示页面,增加提示语“Auto-Renew: Cancel”
2.适配Google Play 要求支持 16 KB 的内存页面大小,更新大部分第三方库到最新版本
2026-04-21 17:20:28 +08:00
yezhiqiu
0dfc082f2b 1.无上报的判断时间,改为动态时间,按用户所设的上报间隔的2倍计算时长
2.修改历史订单包括自动订阅订单
2026-04-20 15:32:29 +08:00
yezhiqiu
bcf03fa149 优化route页交互体验,修复有无数据切换布局错位bug 2026-04-17 15:59:35 +08:00
yezhiqiu
4e46370ec1 优化route页交互体验,修复有无数据切换布局错位bug 2026-04-17 15:43:29 +08:00
yezhiqiu
3b55eaabf4 自动订阅的套餐列表,不显示倒计时,取消自动订阅的套餐才显示 2026-04-16 18:17:46 +08:00
yezhiqiu
1325892780 自动订阅的套餐列表,不显示倒计时,取消自动订阅的套餐才显示 2026-04-16 14:58:00 +08:00
yezhiqiu
06bf4687fe 1.增加g40固件升级
2.优化dfu弹窗布局
2026-04-16 10:42:38 +08:00
yezhiqiu
d8ab8599da 时间统一格式 2026-04-15 11:51:38 +08:00
yezhiqiu
d002310a0d 1.增加G40蓝牙日志上报 2026-04-15 10:36:11 +08:00
yezhiqiu
69aa917897 1.route页ui功能改版 2026-04-14 17:10:34 +08:00
yezhiqiu
20ff76b933 1.新增wifi列表g40根据手机系统wifi来显示wifi名字
2.新增map页地址显示当前wifizone名字
2026-04-09 15:44:08 +08:00
yezhiqiu
862c9c9a06 1.增加默认谷歌地图导航
2.优化人和宠物位置切换
2026-04-09 09:47:27 +08:00
211 changed files with 3878 additions and 864 deletions

View File

@@ -4,10 +4,10 @@
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2026-04-01T06:06:01.472811800Z">
<DropdownSelection timestamp="2026-04-20T07:03:55.586316Z">
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=3A040DLJH000R0" />
<DeviceId pluginId="PhysicalDevice" identifier="serial=R5CT80BHT3Y" />
</handle>
</Target>
</DropdownSelection>

View File

@@ -1 +0,0 @@
o/bundleLibRuntimeToDirDebug

View File

@@ -1 +1 @@
#Thu Mar 19 17:33:53 CST 2026
#Tue Apr 21 16:52:55 CST 2026

View File

@@ -28,9 +28,9 @@ android {
applicationId "com.abbidot.tracker"
minSdkVersion 23
targetSdkVersion 35
versionCode 2112
versionName "2.1.12"
// versionName "2.1.12-Beta4"
versionCode 2205
// versionName "2.2.5"
versionName "2.2.5-Beta1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -63,6 +63,17 @@ android {
]
}
//解决mapBox和百度地图libc++_shared.so发生冲突http://www.52im.net/blog-28523-2848.html
packagingOptions {
pickFirst 'lib/x86/libc++_shared.so'
pickFirst 'lib/x86_64/libc++_shared.so'
pickFirst 'lib/armeabi-v7a/libc++_shared.so'
pickFirst 'lib/arm64-v8a/libc++_shared.so'
pickFirst 'lib/armeabi/libc++_shared.so'
pickFirst 'lib/mips/libc++_shared.so'
pickFirst 'lib/mips64/libc++_shared.so'
}
// 读取local.properties文件
Properties properties = new Properties()
InputStream inputStream = project.rootProject.file('local.properties').newDataInputStream()
@@ -188,23 +199,23 @@ dependencies {
androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
// Android官方库
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
implementation 'androidx.arch.core:core-common:2.2.0'
implementation 'androidx.arch.core:core-runtime:2.2.0'
implementation 'androidx.activity:activity-ktx:1.9.3'
implementation 'androidx.fragment:fragment-ktx:1.5.6'
implementation 'androidx.annotation:annotation:1.9.1'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.8.7'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.8.7'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.7'
implementation 'androidx.activity:activity-ktx:1.10.1'
implementation 'androidx.fragment:fragment-ktx:1.8.9'
implementation 'androidx.annotation:annotation:1.10.0'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.10.0'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.10.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.10.0'
implementation 'androidx.room:room-runtime:2.5.2'
implementation 'androidx.room:room-runtime:2.8.4'
// implementation 'androidx.room:room-rxjava2:2.3.0'
implementation 'androidx.room:room-ktx:2.5.2'
kapt 'androidx.room:room-compiler:2.5.2'
implementation 'androidx.room:room-ktx:2.8.4'
kapt 'androidx.room:room-compiler:2.8.4'
//hilt依赖注入https://mvnrepository.com/artifact/com.google.dagger/hilt-android-gradle-plugin
implementation "com.google.dagger:hilt-android:2.57"
kapt "com.google.dagger:hilt-android-compiler:2.57"
implementation "com.google.dagger:hilt-android:2.57.2"
kapt "com.google.dagger:hilt-android-compiler:2.57.2"
//Android UI 开发效率的 UI 库https://github.com/Tencent/QMUI_Android
implementation 'com.qmuiteam:qmui:2.1.0'
@@ -221,11 +232,11 @@ dependencies {
implementation "io.coil-kt:coil-gif:1.4.0"//支持GIF
//lottie动画https://github.com/airbnb/lottie-android
implementation 'com.airbnb.android:lottie:6.6.7'
implementation 'com.airbnb.android:lottie:6.7.1'
//https://github.com/CymChad/BaseRecyclerViewAdapterHelper
implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.11'
implementation "io.github.cymchad:BaseRecyclerViewAdapterHelper:3.0.14"
//升级recyclerview因BaseRecyclerViewAdapterHelper item点击事件是使用1.2.0
implementation 'androidx.recyclerview:recyclerview:1.3.1'
implementation 'androidx.recyclerview:recyclerview:1.4.0'
//谷歌地图
implementation 'com.google.android.gms:play-services-maps:20.0.0'
@@ -245,21 +256,24 @@ dependencies {
//mapbox地图https://github.com/mapbox/mapbox-maps-android
// implementation 'com.mapbox.maps:android:10.2.0'
//https://github.com/mapbox/mapbox-search-android
//用mapbox搜索SDK,地理编码 有搜索ui组件已包括mapbox-search-android架包
implementation "com.mapbox.search:mapbox-search-android-ui:2.5.1"
/**用mapbox搜索SDK,地理编码 有搜索ui组件已包括mapbox-search-android架包
* 支持 16 KB 页面大小
* https://docs.mapbox.com/android/search/guides/install/#step-2-add-search-sdk-dependencies
*/
implementation "com.mapbox.search:mapbox-search-android-ui-ndk27:2.22.0"
// mapbox搜索SDK,地理编码 没有搜索ui组件
// implementation "com.mapbox.search:mapbox-search-android:1.0.0-beta.25"
//用于计算距离https://docs.mapbox.com/android/java/guides/turf/#available-methods
implementation 'com.mapbox.mapboxsdk:mapbox-sdk-turf:6.15.0'
//用于计算路线规划信息https://docs.mapbox.com/android/java/examples/dashed-directions-line/
implementation 'com.mapbox.mapboxsdk:mapbox-sdk-services:6.3.0'
//用于计算距离https://docs.mapbox.com/android/java/guides/#installation
implementation 'com.mapbox.mapboxsdk:mapbox-sdk-turf:7.10.0'
//用于计算路线规划信息、地理编码
implementation 'com.mapbox.mapboxsdk:mapbox-sdk-services:7.10.0'
// 权限请求框架https://github.com/getActivity/XXPermissions
implementation 'com.github.getActivity:XXPermissions:25.2'
implementation 'com.github.getActivity:XXPermissions:28.2'
// 吐司框架https://github.com/getActivity/ToastUtils
implementation 'com.github.getActivity:Toaster:13.2'
implementation 'com.github.getActivity:Toaster:15.0'
// 日志调试框架https://github.com/getActivity/Logcat ,在debug模式下集成
debugImplementation 'com.github.getActivity:Logcat:12.3'
debugImplementation 'com.github.getActivity:Logcat:13.0'
// PictureSelector图片选择器,需要compileSdkVersion=31 https://github.com/LuckSiege/PictureSelector
// implementation 'io.github.lucksiege:pictureselector:v3.0.3'
@@ -268,14 +282,14 @@ dependencies {
//压缩图片 https://github.com/zetbaitsu/Compressor
implementation 'id.zelory:compressor:3.0.1'
//图片裁剪功能https://github.com/CanHub/Android-Image-Cropper
implementation 'com.vanniktech:android-image-cropper:4.6.0'
implementation 'com.vanniktech:android-image-cropper:4.7.0'
//******************************************极光推送start*****************************************************
// https://docs.jiguang.cn/jpush/client/Android/android_guide
// implementation 'cn.jiguang.sdk:jcore:3.1.2' // 此处以JCore 2.7.2 版本为例。
// implementation 'cn.jiguang.sdk:jpush:4.6.0' // 此处以JPush 4.0.0 版本为例
implementation 'cn.jiguang.sdk:jcore-google:5.1.0' // 此处以JCore 2.7.2 版本为例。
implementation 'cn.jiguang.sdk:jpush-google:5.8.0' // 此处以JPush 4.0.0 版本为例
implementation 'cn.jiguang.sdk:jcore-google:5.3.7' // 此处以JCore 2.7.2 版本为例。
implementation 'cn.jiguang.sdk:jpush-google:6.0.7' // 此处以JPush 4.0.0 版本为例
// 接入华为厂商
// implementation 'com.huawei.hms:push:6.1.0.300'
// implementation 'cn.jiguang.sdk.plugin:huawei:4.0.0'// 极光厂商插件版本与接入 JPush 版本保持一致,下同
@@ -294,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'
@@ -306,24 +320,27 @@ dependencies {
implementation 'com.stripe:stripe-android:20.27.0'
//百度地图基础定位组件
implementation 'com.baidu.lbsyun:BaiduMapSDK_Location:9.6.5.1'
implementation 'com.baidu.lbsyun:BaiduMapSDK_Location:9.6.7'
//地图组件
implementation 'com.baidu.lbsyun:BaiduMapSDK_Map:7.5.2'
implementation 'com.baidu.lbsyun:BaiduMapSDK_Map:7.6.7'
//检索组件
implementation 'com.baidu.lbsyun:BaiduMapSDK_Search:7.5.2'
implementation 'com.baidu.lbsyun:BaiduMapSDK_Search:7.6.7'
//工具组件
implementation 'com.baidu.lbsyun:BaiduMapSDK_Util:7.5.2'
implementation 'com.baidu.lbsyun:BaiduMapSDK_Util:7.6.7'
//微信登录、支付
implementation 'com.tencent.mm.opensdk:wechat-sdk-android:+'
//支付宝支付
implementation 'com.alipay.sdk:alipaysdk-android:+@aar'
//dfu升级https://github.com/NordicSemiconductor/Android-DFU-Library
implementation 'no.nordicsemi.android:dfu:2.9.0'
//g30 dfu升级https://github.com/NordicSemiconductor/Android-DFU-Library
implementation 'no.nordicsemi.android:dfu:2.10.1'
//g40 dfu升级https://github.com/nordicsemi/Android-nRF-Connect-Device-Manager?tab=readme-ov-file#migration-from-the-original-repo
// implementation 'no.nordicsemi.android:mcumgr-core:2.7.4'
implementation 'no.nordicsemi.android:mcumgr-ble:2.7.4'
//适配Android 12以下SplashScreen启动动画闪屏图片
implementation 'androidx.core:core-splashscreen:1.0.1'
implementation 'androidx.core:core-splashscreen:1.2.0'
//优雅、万能自定义日历https://github.com/huanghaibin-dev/CalendarView
// implementation 'com.haibin:calendarview:3.7.1'
//https://github.com/angcyo/CalendarView

View File

@@ -55,7 +55,6 @@
android:protectionLevel="signature" /> <!-- Optional. Required for location feature -->
<uses-permission android:name="${applicationId}.permission.JPUSH_MESSAGE" /> <!-- 为了提高sdk识别唯一用户的能力保证消息推送的精准送达建议集成以下权限可选 -->
<!-- <uses-permission -->
<!-- android:name="android.permission.QUERY_ALL_PACKAGES" -->
<!-- tools:ignore="QueryAllPackagesPermission" /> -->
<!-- 如您需要接入地理围栏业务,建议集成以下权限(可选) -->
<uses-permission android:name="android.permission.GET_TASKS" /> <!-- 如您需要对应设备通知相关的能力,建议集成以下权限(可选) -->
@@ -386,7 +385,8 @@
<activity
android:name=".ui.activity.device.wifi.EditWifiPowerZoneActivity"
android:exported="false"
android:screenOrientation="portrait" />
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan" />
<activity
android:name=".ui.activity.map.LiveActivityV3"
android:exported="false"

View File

@@ -2,19 +2,50 @@
<body>
<div>
<h3>ABBIDOT Tracker Subscription Terms and Conditions
</h3>
<p>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.
<p>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.</p>
<p>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.</p>
<p>4.Modifications ABBIDOT reserves the right to update these terms. Users will be notified of changes. By subscribing, you agree to these terms.</p>
<p>For support contact:</p>
<p>support@abbidot.com</p>
<h2>ABBIDOT Tracker Subscription Terms and Conditions</h2>
<hr>
<h3>1. Subscription Plans</h3>
<p>ABBIDOT offers three subscription plans:</p>
<ul>
<li>3-Month Plan</li>
<li>1-Year Plan</li>
<li>2-Year Plan</li>
</ul>
<p>All subscriptions are automatically renewed at the end of each billing cycle unless canceled by the user.</p>
<p>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.</p>
<p>The device will continue to function normally during the active subscription period.</p>
<hr>
<h3>2. Refund Policy</h3>
<h4>2.1 Automatic Refund (Within 48 Hours)</h4>
<p>All subscription purchases are eligible for a <strong>full automatic refund within 48 hours</strong> of payment. Refunds will be processed automatically without manual review.</p>
<hr>
<h4>2.2 Standard Refund Window (30 Days)</h4>
<p>After the initial 48-hour period, users may request a refund within <strong>30 days of purchase.</strong></p>
<ul>
<li>All subscription plans (3-Month, 1-Year, 2-Year) are eligible</li>
<li>Refund requests are subject to review and approval</li>
<li>Refunds may be partially adjusted based on usage and service consumption</li>
</ul>
<hr>
<h4>2.3 No Refund After 30 Days</h4>
<p>Subscriptions older than 30 days are non-refundable.</p>
<hr>
<h3>3. Subscription Cancellation</h3>
<p>Users may cancel their subscription at any time.</p>
<ul>
<li>Cancellation stops future billing</li>
<li>The current subscription remains active until the end of the billing period</li>
<li>No partial refund is issued after cancellation unless within the refund window</li>
</ul>
<hr>
<h3>4. Policy Updates</h3>
<p>ABBIDOT reserves the right to update or modify these Terms and Conditions at any time. Users will be notified of significant changes.</p>
<p>By subscribing to ABBIDOT services, you agree to these terms.</p>
<hr>
<h3>5. Customer Support</h3>
<p>If you encounter any difficulties, please contact us at:</p>
<p><a title="Mail to subscription@abbidot.com" href="subscription@abbidot.com">subscription@abbidot.com</a></p>
<p>Our support team will assist you as soon as possible.</p>
</div>

View File

@@ -1,12 +1,13 @@
package com.abbidot.tracker.adapter
import android.graphics.Typeface
import android.widget.ImageView
import android.util.TypedValue
import androidx.appcompat.widget.AppCompatImageView
import androidx.core.content.ContextCompat
import com.abbidot.baselibrary.util.AppUtils
import com.abbidot.tracker.R
import com.abbidot.tracker.bean.MenuTxtBean
import com.abbidot.tracker.constant.ConstantInt
import com.abbidot.tracker.constant.MultipleEntity
import com.abbidot.tracker.widget.TypefaceTextView
import com.chad.library.adapter.base.BaseMultiItemQuickAdapter
@@ -32,6 +33,8 @@ class HelpTextImageTypeAdapter(list: MutableList<MenuTxtBean>?) :
addItemType(MultipleEntity.IMG_IMG, R.layout.layout_help_title1)
//显示14sp大小的文字内容
addItemType(MultipleEntity.IMG_TEXT_IMG, R.layout.layout_help_title2)
//显示多大字体,是否粗体,字体颜色
addItemType(MultipleEntity.TEXT_TEXT_IMG, R.layout.layout_help_title2)
}
override fun convert(holder: BaseViewHolder, item: MenuTxtBean) {
@@ -67,6 +70,23 @@ class HelpTextImageTypeAdapter(list: MutableList<MenuTxtBean>?) :
holder.getView<TypefaceTextView>(R.id.tv_help_title_two).text = item.menuName
holder.itemView.setPadding(0, AppUtils.dpToPx(14), 0, 0)
}
MultipleEntity.TEXT_TEXT_IMG -> {
holder.getView<TypefaceTextView>(R.id.tv_help_title_two).apply {
//是否粗体
val typefaceBold =
if (item.isSwitch) Typeface.create(Typeface.DEFAULT, Typeface.BOLD)
else Typeface.create(Typeface.DEFAULT, Typeface.NORMAL)
typeface = typefaceBold
text = item.menuName
setTextSize(TypedValue.COMPLEX_UNIT_SP, item.state.toFloat())
val tColor = if (item.colorRedId == ConstantInt.Type0) R.color.data_black_color
else item.colorRedId
setTextColor(ContextCompat.getColor(context, tColor))
}
// holder.itemView.setPadding(0, AppUtils.dpToPx(14), 0, 0)
}
}
}

View File

@@ -0,0 +1,67 @@
package com.abbidot.tracker.adapter
import android.content.Context
import android.text.format.DateUtils
import android.view.View
import com.abbidot.baselibrary.list.BaseRecyclerAdapter
import com.abbidot.baselibrary.list.RecyclerViewHolder
import com.abbidot.baselibrary.util.Utils
import com.abbidot.tracker.R
import com.abbidot.tracker.bean.MessageBean
import com.abbidot.tracker.constant.ConstantInt
/**
*Created by .yzq on 2026/4/10/周五.
* @link
* @description:
*/
class HistoryFenceAdapter(
ctx: Context, list: MutableList<MessageBean>?
) : BaseRecyclerAdapter<MessageBean>(ctx, list) {
override fun getEmptyLayoutId(viewType: Int) = 0
override fun getItemLayoutId(viewType: Int) = R.layout.item_history_fence_layout
override fun bindData(holder: RecyclerViewHolder?, position: Int, item: MessageBean) {
holder?.apply {
getImageView(R.id.iv_history_fence_type_image).let {
when (item.deviceMessageType) {
ConstantInt.Type1, ConstantInt.Type3 -> it.setImageResource(R.drawable.icon_history_danger_fence_image)
ConstantInt.Type2 -> it.setImageResource(R.drawable.icon_history_save_fence_image)
ConstantInt.Type4 -> it.setImageResource(R.drawable.icon_history_no_save_fence_image)
}
}
getTextView(R.id.tv_history_fence_type_time).text =
getRelativeTimeString(item.timeStamp)
getTextView(R.id.tv_history_fence_type_content).text = item.message
getImageView(R.id.iv_history_fence_type_line).let {
it.visibility = if (position == getData().size - 1) View.GONE
else View.VISIBLE
}
}
}
private fun getRelativeTimeString(timeStamp: Long): String {
val formatDateStr: String
val cTimeStamp = Utils.stringToTimestamp(
Utils.formatTime(
timeStamp, Utils.DATE_FORMAT_PATTERN_CN2
)
)
val now = System.currentTimeMillis()
formatDateStr = if (DateUtils.isToday(cTimeStamp)) {
mContext.getString(R.string.txt_today) + " " + Utils.formatTime(
timeStamp, Utils.DATE_FORMAT_PATTERN_EN14
)
} else if (now - cTimeStamp < (48 * 60 * 60 * 1000)) {
mContext.getString(R.string.txt_yesterday) + " " + Utils.formatTime(
timeStamp, Utils.DATE_FORMAT_PATTERN_EN14
)
} else {
Utils.formatTime(
timeStamp, Utils.DATE_FORMAT_PATTERN_EN15
)
}
return formatDateStr
}
}

View File

@@ -80,7 +80,7 @@ class MySubscriptionAdapter(
}
holder.setText(
R.id.tv_my_subscription_active_time,
Utils.formatTime(item.payTime, Utils.DATE_FORMAT_PATTERN_EN6)
Utils.formatTime(item.payTime, Utils.DATE_FORMAT_PATTERN_CN4)
)
holder.getTextView(R.id.tv_my_subscription_annual_care).apply {
@@ -91,12 +91,12 @@ class MySubscriptionAdapter(
holder.getTextView(R.id.tv_my_subscription_expires_on).apply {
text = if (item.orderStatus == 6 && item.refundTime > 0L) {
Utils.formatTime(item.refundTime, Utils.DATE_FORMAT_PATTERN_EN6)
Utils.formatTime(item.refundTime, Utils.DATE_FORMAT_PATTERN_CN4)
} else {
Utils.formatTime(
Utils.timestampAddHowTimestamp(
item.payTime, item.mealPeriod, item.mealUnit
), Utils.DATE_FORMAT_PATTERN_EN7
), Utils.DATE_FORMAT_PATTERN_CN
)
}
}
@@ -147,9 +147,27 @@ class MySubscriptionAdapter(
}
val times = Utils.differYear(cTimeMillis, item.endTime)
holder.setText(R.id.tv_add_success_device_expires_days, times[0])
holder.setText(R.id.tv_add_success_device_expires_hours, times[1])
holder.setText(R.id.tv_add_success_device_expires_min, times[2])
holder.getTextView(R.id.tv_add_success_device_expires_days).apply {
visibility = if (item.subscriptionStatus == ConstantInt.Close) {
text = times[0]
View.VISIBLE
} else View.GONE
holder.getTextView(R.id.tv_add_device_expires_year_title).visibility = visibility
}
holder.getTextView(R.id.tv_add_success_device_expires_hours).apply {
visibility = if (item.subscriptionStatus == ConstantInt.Close) {
text = times[1]
View.VISIBLE
} else View.GONE
holder.getTextView(R.id.tv_add_device_expires_month_title).visibility = visibility
}
holder.getTextView(R.id.tv_add_success_device_expires_min).apply {
visibility = if (item.subscriptionStatus == ConstantInt.Close) {
text = times[2]
View.VISIBLE
} else View.GONE
holder.getTextView(R.id.tv_add_device_expires_day_title).visibility = visibility
}
holder.getView(R.id.fl_my_subscription_btn_layout).apply {
//UserId不一样就是共享设备的订单
@@ -187,7 +205,7 @@ class MySubscriptionAdapter(
setOnClickListener {
qMUIPopups.dismiss()
Intent(mContext, SubscriptionHistoryActivity::class.java).let {
it.putExtra(ConstantString.DeviceId, item.deviceId)
it.putExtra(ConstantString.Id, item.subscriptionId)
mMySubscriptionActivity.startActivity(it)
}
}

View File

@@ -58,7 +58,7 @@ class NotificationV2Adapter(
}
private fun getRelativeTimeString(timeStamp: Long): String {
var formatDateStr = ""
val formatDateStr: String
val cTimeStamp = Utils.stringToTimestamp(
Utils.formatTime(
timeStamp, Utils.DATE_FORMAT_PATTERN_CN2
@@ -67,15 +67,15 @@ class NotificationV2Adapter(
val now = System.currentTimeMillis()
formatDateStr = if (DateUtils.isToday(cTimeStamp)) {
mContext.getString(R.string.txt_today) + " " + Utils.formatTime(
timeStamp, Utils.DATE_FORMAT_PATTERN_EN8
timeStamp, Utils.DATE_FORMAT_PATTERN_EN14
)
} else if (now - cTimeStamp < (48 * 60 * 60 * 1000)) {
mContext.getString(R.string.txt_yesterday) + " " + Utils.formatTime(
timeStamp, Utils.DATE_FORMAT_PATTERN_EN8
timeStamp, Utils.DATE_FORMAT_PATTERN_EN14
)
} else {
Utils.formatTime(
timeStamp, Utils.DATE_FORMAT_PATTERN_EN9
timeStamp, Utils.DATE_FORMAT_PATTERN_CN2
)
}
return formatDateStr

View File

@@ -1,5 +1,6 @@
package com.abbidot.tracker.adapter
import android.content.Context
import android.content.Intent
import android.view.View
import android.widget.TextView
@@ -16,6 +17,8 @@ import com.abbidot.tracker.ui.activity.subscribe.SubscriptionHistoryActivity
import com.abbidot.tracker.widget.TypefaceRoundButton
import com.chad.library.adapter.base.BaseMultiItemQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.hjq.toast.Toaster
import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButtonDrawable
/**
*Created by .yzq on 2024/8/19/019.
@@ -46,6 +49,9 @@ class SubscriptionHistoryAdapter(
}
}
/**
* 保险订单
*/
private fun bindAnnualCareData(holder: BaseViewHolder, item: SubscriptionsOrderBean) {
holder.setText(
R.id.tv_subscription_annual_care_order_id,
@@ -63,7 +69,7 @@ class SubscriptionHistoryAdapter(
holder.setText(R.id.tv_subscription_annual_care_state, state)
holder.setText(
R.id.tv_subscription_annual_care_active_time, Utils.formatTime(
item.payTime, Utils.DATE_FORMAT_PATTERN_EN7
item.payTime, Utils.DATE_FORMAT_PATTERN_CN
)
)
//保险时长不足一年按12个月算
@@ -73,7 +79,7 @@ class SubscriptionHistoryAdapter(
R.id.tv_subscription_annual_care_expiry_time, Utils.formatTime(
Utils.timestampAddHowTimestamp(
item.payTime, insuranceTime, ConstantString.PackageUnitYear
), Utils.DATE_FORMAT_PATTERN_EN7
), Utils.DATE_FORMAT_PATTERN_CN
)
)
holder.setText(
@@ -93,7 +99,7 @@ class SubscriptionHistoryAdapter(
)
holder.setText(
R.id.tv_subscription_history_order_time,
Utils.formatTime(item.payTime, Utils.DATE_FORMAT_PATTERN_EN10)
Utils.formatTime(item.payTime, Utils.DATE_FORMAT_PATTERN_CN2)
)
holder.setText(R.id.tv_subscription_history_package_name, item.mealName)
holder.setText(
@@ -111,33 +117,39 @@ class SubscriptionHistoryAdapter(
visibility = View.VISIBLE
when (item.orderStatus) {
1 -> {
val updateTimestamp = Utils.stringToTimestamp(item.updateTime, isUtc = true)
val nowTimestamp = System.currentTimeMillis()
if (item.enabled == ConstantInt.Type0 || (item.surplusDays == 0L && item.subscriptionStatus == ConstantInt.Close)) {
if (item.isAutoRenewal == ConstantInt.Type1) {
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
//套餐超出7天不能退款
if (nowTimestamp - updateTimestamp <= day7Timestamp) {
visibility = View.VISIBLE
setText(R.string.txt_refund)
} else {
visibility = View.GONE
}
} else {
val day30Timestamp = 30 * 24 * 60 * 60 * 1000L
//套餐超出30天不能退款
if (nowTimestamp - updateTimestamp <= day30Timestamp) {
visibility = View.VISIBLE
setText(R.string.txt_refund)
} else {
visibility = View.GONE
}
setRefundState(context, item.isRefundable, this)
}
setTextColor(ContextCompat.getColor(context, R.color.select_color))
// 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
// //套餐超出7天不能退款
// if (nowTimestamp - updateTimestamp <= day7Timestamp) {
// visibility = View.VISIBLE
// setText(R.string.txt_refund)
// } else {
// visibility = View.GONE
// }
// } else {
// val day30Timestamp = 30 * 24 * 60 * 60 * 1000L
// //套餐超出30天不能退款
// if (nowTimestamp - updateTimestamp <= day30Timestamp) {
// visibility = View.VISIBLE
// setText(R.string.txt_refund)
// } else {
// visibility = View.GONE
// }
// }
// setTextColor(ContextCompat.getColor(context, R.color.select_color))
}
4 -> setText(R.string.txt_waiting)
@@ -155,6 +167,10 @@ class SubscriptionHistoryAdapter(
setChangeAlphaWhenPress(true)
setOnClickListener {
if (item.orderStatus == ConstantInt.Type1) {
if (item.isRefundable == ConstantInt.Type0) {
Toaster.show(R.string.txt_refund_expired)
return@setOnClickListener
}
Intent(context, RequestRefundActivity::class.java).apply {
putExtra(ConstantString.SetMeal, item)
mHistoryActivity.startActivity(this)
@@ -166,12 +182,11 @@ class SubscriptionHistoryAdapter(
val cTimeMillis = System.currentTimeMillis()
val endTime = if (item.refundTime == 0L) item.endTime else item.refundTime
val expiredTime = endTime * 1000 - cTimeMillis
val state =
if (item.enabled == ConstantInt.Type0 || (item.subscriptionStatus == ConstantInt.Close && expiredTime <= 0)) {
context.getString(R.string.txt_expired)
} else {
context.getString(R.string.txt_active)
}
val state = if (item.enabled == ConstantInt.Type0 || (expiredTime <= 0)) {
context.getString(R.string.txt_expired)
} else {
context.getString(R.string.txt_active)
}
holder.setText(R.id.tv_subscription_history_subscription_state, state)
holder.getView<TextView>(R.id.tv_subscription_history_annual_care).apply {
@@ -181,4 +196,24 @@ class SubscriptionHistoryAdapter(
}
}
private fun setRefundState(
context: Context, isRefundable: Int, roundButton: TypefaceRoundButton
) {
roundButton.apply {
var textColor = R.color.select_color
val strokeColor = if (isRefundable == ConstantInt.Type1) {
R.color.block_color
} else {
textColor = R.color.line_color1
R.color.permission_no_check_color
}
(background as QMUIRoundButtonDrawable).let {
it.setStroke(
it.strokeWidth, ContextCompat.getColor(context, strokeColor)
)
}
setTextColor(ContextCompat.getColor(context, textColor))
}
}
}

View File

@@ -0,0 +1,41 @@
package com.abbidot.tracker.adapter;
import android.content.Context;
import android.view.View;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
/**
* Created by .yzq on 2026/4/13/周一.
*
* @link
* @description:
*/
public class TopSlideLayoutManager extends LinearLayoutManager {
private int mTopOffset;
public TopSlideLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
public void setTopOffset(int topOffset) {
mTopOffset = topOffset;
requestLayout();
}
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
super.onLayoutChildren(recycler, state);
// 可以在这里调整子项的位置,例如将顶部几个项上移
if (getChildCount() > 0) {
View firstChild = getChildAt(0);
if (firstChild != null) {
int top = getDecoratedTop(firstChild) - mTopOffset;
layoutDecoratedWithMargins(firstChild, firstChild.getLeft(), top,
firstChild.getRight(), top + firstChild.getHeight());
}
}
}
}

View File

@@ -61,7 +61,7 @@ abstract class BaseActivity<T : ViewBinding>(val inflater: (inflater: LayoutInfl
private var mLoadingDialog: QMUITipDialog? = null
//默认删除去掉titleTopBar底部间隔下划线
var mDeleteBottomDivider: Boolean = true
private var mDeleteBottomDivider: Boolean = true
//Activity是否在前台显示运行
var isFrontRunning = false
@@ -86,8 +86,8 @@ abstract class BaseActivity<T : ViewBinding>(val inflater: (inflater: LayoutInfl
// 监听因输入框弹出,遮挡输入框,界面移动,需要移动的view
private var mTranslateView: View? = null
/*****************************监听软键盘弹出,输入框上移start************************************/
private var isKeyboardTranslate = true
/*****************************监听软键盘弹出,输入框上移 ************************************/
var isKeyboardTranslate = true
//是否需要适配底部EdgeToEdge
var isEdgeToEdgeAdapterNavigationBars = true
@@ -168,6 +168,7 @@ abstract class BaseActivity<T : ViewBinding>(val inflater: (inflater: LayoutInfl
override fun onPause() {
super.onPause()
isFrontRunning = false
//键盘隐藏恢复默认状态
mTranslateView?.apply {
scrollTo(0, 0)
@@ -231,16 +232,25 @@ abstract class BaseActivity<T : ViewBinding>(val inflater: (inflater: LayoutInfl
/**
* 监听键盘弹出和隐藏,解决键盘弹出挡住输入框的问题
*/
fun setListenKeyboardChange(windowTranslateY: Int = 500, view: View = window.decorView) {
fun setListenKeyboardChange(
windowTranslateY: Int = 500,
view: View = window.decorView,
methodType: Int = ConstantInt.Type0
) {
val metrics = getResources().displayMetrics
val screenWidth = metrics.widthPixels
// val screenHeight = metrics.heightPixels
val scaleFactor = screenWidth / 1080 // 假设 1080 是设计宽度
window.decorView.viewTreeObserver.addOnGlobalLayoutListener {
onLayoutChange(view, windowTranslateY * scaleFactor)
view.viewTreeObserver.addOnGlobalLayoutListener {
if (methodType == ConstantInt.Type0) {
onLayoutChange(view, windowTranslateY * scaleFactor)
} else {
onGlobalLayoutChange(view, windowTranslateY * scaleFactor)
}
}
}
/**
* 设置其他包含的view点击。隐藏软键盘如ScrollView
*/
@@ -560,16 +570,24 @@ abstract class BaseActivity<T : ViewBinding>(val inflater: (inflater: LayoutInfl
val exceptionMessage = it.exceptionOrNull()?.message
//服务器返回错误code
val exceptionCode: String? = it.exceptionOrNull()?.toString()
LogUtil.d("Throwable", "code=${exceptionCode},${exceptionMessage}")
LogUtil.d("Throwable异常", "code=${exceptionCode},${exceptionMessage}")
if (null != exceptionCode) {
//处理注册用户已存在的情况
if (exceptionCode == ErrorCode.USER_HAS_EXIST.toString()) {
getResultCallback.onRequestError(exceptionCode)
}
if (exceptionCode == ErrorCode.DEVICE_HAS_BIND.toString()) {
val str =
String.format(getString(R.string.txt_device_has_bind), exceptionMessage)
showToast(str)
getResultCallback.onInterceptCode()
return
}
//拦截请求异常code
if (netErrorCodeTips(exceptionCode, isShowCodeError)) {
else if (netErrorCodeTips(exceptionCode, isShowCodeError)) {
//已经处理相关错误码就直接返回
getResultCallback.onErrorCode()
getResultCallback.onInterceptCode()
return
}
}
@@ -675,10 +693,10 @@ abstract class BaseActivity<T : ViewBinding>(val inflater: (inflater: LayoutInfl
return true
}
//该设备已被绑定
ErrorCode.DEVICE_HAS_BIND.toString() -> {
if (isShowCodeError) showToast(R.string.txt_device_has_bind)
return true
}
// ErrorCode.DEVICE_HAS_BIND.toString() -> {
// if (isShowCodeError) showToast(R.string.txt_device_has_bind)
// return true
// }
//设备不存在
ErrorCode.DEVICE_NOT_EXIST.toString() -> {
if (isShowCodeError) showToast(R.string.txt_no_dfu)
@@ -834,10 +852,10 @@ abstract class BaseActivity<T : ViewBinding>(val inflater: (inflater: LayoutInfl
private fun onLayoutChange(translateView: View, translateY: Int) {
mTranslateView = translateView
//获取当前屏幕内容的高度
val screenHeight = window.decorView.height
val screenHeight = translateView.height
//获取View可见区域的bottom
val rect = Rect()
window.decorView.getWindowVisibleDisplayFrame(rect)
translateView.getWindowVisibleDisplayFrame(rect)
if (screenHeight - getNavigatorBarHeight() > rect.bottom) {
// 获取按钮的左上角按钮高度为40dp
// val location = IntArray(2)
@@ -845,7 +863,7 @@ abstract class BaseActivity<T : ViewBinding>(val inflater: (inflater: LayoutInfl
// val bottom = location[1] + resources.getDimensionPixelSize(R.dimen.dp_80)
//// 如果按钮被覆盖,移动整个界面向上移动
// if (bottom > rect.bottom) {
// window.decorView.scrollBy(0, bottom - rect.bottom)
// translateView.scrollBy(0, bottom - rect.bottom)
// isKeyboardTranslate = true
// }
if (!isKeyboardTranslate) {
@@ -864,5 +882,28 @@ abstract class BaseActivity<T : ViewBinding>(val inflater: (inflater: LayoutInfl
hideSoftKeyboardCallback()
}
}
private fun onGlobalLayoutChange(translateView: View, translateY: Int) {
mTranslateView = translateView
val r = Rect()
translateView.getWindowVisibleDisplayFrame(r)
val heightDiff = translateView.getRootView().height - (r.bottom - r.top)
if (heightDiff > 200) { // 如果高度差大于200说明键盘是弹出的
// 进行布局调整
if (!isKeyboardTranslate) {
//移动到指定位置点坐标
translateView.scrollBy(0, translateY)
isKeyboardTranslate = true
}
LogUtil.e("如果高度差大于200说明键盘是弹出的")
showSoftKeyboardCallback()
} else {
// 键盘隐藏,恢复布局
isKeyboardTranslate = false
LogUtil.e("键盘隐藏,恢复布局")
translateView.scrollTo(0, 0)
hideSoftKeyboardCallback()
}
}
/*****************************监听软键盘弹出输入框上移end************************************/
}

View File

@@ -9,12 +9,16 @@ import kotlinx.parcelize.Parcelize
* @description:设备详情
*/
@Parcelize
data class DeviceDetailBean(var deviceOutId: String,
var deviceId: String,
var macId: String,
var pet: PetBean?,
var fenceCount: Int,
var surplusDays: Int,
var familieCount: Int,var deviceInfo:DeviceInfoBean?) : Parcelable {
constructor() : this("", "", "", null, 0, 0,0,null)
data class DeviceDetailBean(
var deviceOutId: String,
var deviceId: String,
var macId: String,
var email: String,
var pet: PetBean?,
var fenceCount: Int,
var surplusDays: Int,
var familieCount: Int,
var deviceInfo: DeviceInfoBean?
) : Parcelable {
constructor() : this("", "", "", "", null, 0, 0, 0, null)
}

View File

@@ -36,6 +36,7 @@ data class MapDeviceBean(
var startTime: String,
var endTime: String,
var deviceType: Int,
var wifiZoneName: String,
var notifyLocationFail: Boolean,
var canShowBattery: Boolean,//是否可以显示电池提示布局
var isCloseBattery: Boolean,//是否关闭电池提示
@@ -72,6 +73,7 @@ data class MapDeviceBean(
"",
"",
1,
"",
false,
false,
false,

View File

@@ -18,8 +18,9 @@ data class PayResultBean(
var expirationTime: String,
var deviceOutId: String,
var deviceId: String,
var deviceType: Int,
//设备充值类型0=首次设备充值激活1=已添加设备再次添加设备充值2=给当前的设备续费或者升级套餐
var rechargeType: Int
) : Parcelable {
constructor() : this("", "", "", 0L, "", "", "", ConstantInt.Type1)
constructor() : this("", "", "", 0L, "", "", "", 1, ConstantInt.Type1)
}

View File

@@ -55,6 +55,8 @@ data class SubscriptionsOrderBean(
var endTime: Long,
var refundTime: Long,
var planTimeMonthsCount: Int,
var isRefundable: Int,//是否显示退款按钮 1:是 0:否
var isAutoRenewal: Int,//是否是自动续订 1:是 0:否
@MultipleEntity var menuType: Int,
var isUpdateOrder: Int = 0//是否是升级订单 1:是 0:否
) : Parcelable, MultiItemEntity {
@@ -101,6 +103,8 @@ data class SubscriptionsOrderBean(
0L,
0L,
0,
0,
0,
menuType,
0
)
@@ -148,6 +152,8 @@ data class SubscriptionsOrderBean(
0L,
0L,
0,
0,
0,
MultipleEntity.TEXT,
0
)

View File

@@ -49,6 +49,8 @@ import androidx.annotation.IntDef
ConstantInt.BasicPackage,
ConstantInt.PremiumPackage,
ConstantInt.MinSportGoal,
ConstantInt.PetSpecialType,
ConstantInt.DefaultType,
ConstantInt.NoShare,
ConstantInt.ReportTimeOutTime,
ConstantInt.PetLocationType
@@ -100,6 +102,8 @@ annotation class ConstantInt {
const val OtherLocationType = 2
const val UserLocationType = 1
const val PetLocationType = 0
const val PetSpecialType = 3
const val DefaultType = 4
//默认的运动目标时间(min)
const val DefaultSportGoal = 60

View File

@@ -10,5 +10,6 @@ interface GetResultCallback {
//默认可以不重写相当于java中的default修饰的
fun onRequestError(exceptionCode: String?) {}
fun onErrorCode() {}
//已拦截的code
fun onInterceptCode() {}
}

View File

@@ -0,0 +1,10 @@
package com.abbidot.tracker.constant
/**
*Created by .yzq on 2026/4/8/周三.
* @link
* @description:
*/
interface LinkMapCallback {
fun onCameraListener(type:Int)
}

View File

@@ -9,6 +9,7 @@ import com.abbidot.tracker.util.Util
import com.baidu.mapapi.search.route.BikingRouteResult
import com.baidu.mapapi.search.route.DrivingRouteResult
import com.baidu.mapapi.search.route.IndoorRouteResult
import com.baidu.mapapi.search.route.IntegralRouteResult
import com.baidu.mapapi.search.route.MassTransitRouteResult
import com.baidu.mapapi.search.route.OnGetRoutePlanResultListener
import com.baidu.mapapi.search.route.PlanNode
@@ -144,6 +145,10 @@ class RoutePlanningViewModel : ViewModel() {
override fun onGetBikingRouteResult(p0: BikingRouteResult?) {
}
override fun onGetIntegralRouteResult(p0: IntegralRouteResult?) {
}
})
}

View File

@@ -17,7 +17,8 @@ class DFUNewDialog(context: Context) :
private var mVersion = ""
override fun initView() {
setCanceledOnTouchOutside(false)
// setCanceledOnTouchOutside(false)
setCancelable(false)
mViewBinding.apply {
btnDialogDfuNewUpgradeNow.setChangeAlphaWhenPress(true)
setOnClickListenerViews(tvDialogDfuNewLaterBtn, btnDialogDfuNewDone)
@@ -25,8 +26,8 @@ class DFUNewDialog(context: Context) :
}
fun startDfuState(version: String, onClick: () -> Unit) {
mVersion = version
val ver = String.format(mContext.getString(R.string.txt_new_firmware_version), mVersion)
mVersion = "\t$version"
val ver = String.format(mContext.getString(R.string.txt_about_version), mVersion)
mViewBinding.apply {
rlDialogDfuNewAfterLayout.visibility = View.GONE
llDialogDfuNewBeforeLayout.visibility = View.VISIBLE
@@ -36,7 +37,7 @@ class DFUNewDialog(context: Context) :
inDFUState()
onClick()
}
0 }
}
}
private fun inDFUState() {

View File

@@ -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>(
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, false)
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
}
}

View File

@@ -21,15 +21,17 @@ import java.util.Calendar
* @link
* @description:显示日历弹窗
* @param canSelectFutureDate 平时正常日期true不能选择未来时间
* @param minLastDayRange 最小天数能选最近多少天0表示没有限制
*/
class ShowCalenderAndTimeDialog(
context: Context,
showCalenderTextView: TextView,
okListener: OnDialogOkListener? = null,
okListener: OnDialogSelectListener? = null,
format: String = Utils.DATE_FORMAT_PATTERN_EN1,
canSelectFutureDate: Boolean = false,
calenderShowTimestamp: Long = 0,
minYear: Int = 2023
minYear: Int = 2023,
minLastDayRange: Int = 0
) : BaseDialog<DialogCalenderAndTimeLayoutBinding>(
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()
@@ -86,7 +105,7 @@ class ShowCalenderAndTimeDialog(
0,
23,
5,
24,
16,
NumberPickerValueFill0Format(),
this@ShowCalenderAndTimeDialog
)
@@ -98,14 +117,12 @@ class ShowCalenderAndTimeDialog(
0,
59,
5,
24,
16,
NumberPickerValueFill0Format(),
this@ShowCalenderAndTimeDialog
)
}
//根据传入的时间戳进行还原显示
setSelectDate(mCalenderShowTimestamp)
setOnClickListenerViews(
llDialogCalenderLayout.ivSelectCalendarMonthLeft,
@@ -117,6 +134,12 @@ class ShowCalenderAndTimeDialog(
}
}
override fun onStart() {
super.onStart()
//根据传入的时间戳进行还原显示
setSelectDate(mCalenderShowTimestamp)
}
/**
* 根据传入的时间戳进行还原显示
* @param showTimestamp 13位时间戳
@@ -172,16 +195,18 @@ class ShowCalenderAndTimeDialog(
}:${Utils.fill2Digits(npDialogCalenderMin.value)}:00"
val timesTamp = Utils.stringToTimestamp(selectMonthYear)
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
)
mOkListener?.onSelectClick(this@ShowCalenderAndTimeDialog, timesTamp)
}
mOkListener?.onOkClick(this@ShowCalenderAndTimeDialog)
dismiss()
}
}

View File

@@ -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

View File

@@ -837,6 +837,16 @@ interface INetworkService {
@Query("toTime") toTime: Long
): BaseResponse<MutableList<HistoryDataBean>>
/**
* 获取设备进出围栏历史数据
*/
@GET("data/getHistoryInOutFenceList")
suspend fun getHistoryFenceList(
@Query("deviceId") deviceId: String,
@Query("beginTimeStamp") fromTime: Long,
@Query("endTimeStamp") toTime: Long
): BaseResponse<MutableList<MessageBean>>
/**
* 设置运动目标
*/
@@ -1275,13 +1285,21 @@ interface INetworkService {
@Query("userId") userId: String, @Query("deviceId") deviceId: String
): BaseResponse<MutableList<SubscriptionsOrderBean>>
/**
* 获取设备充值得的历史记录(包括自动续订)
*/
@GET("order$SUBSCRIPTIONS_V3/subscriptions/historyIncludRenew")
suspend fun getHistoryIncludeRenew(
@Query("subscriptionId") subscriptionId: String
): BaseResponse<MutableList<SubscriptionsOrderBean>>
/**
* 提交退款申请
*/
@FormUrlEncoded
@POST("order$SUBSCRIPTIONS_V3/refund/commit")
suspend fun commitRefund(
@Field("currency_code") currency_code: String,
@Field("currency_code") currencyCode: String,
@Field("orderNum") orderNum: String,
@Field("chargeId") chargeId: String,
@Field("amount") amount: Int,

View File

@@ -753,6 +753,13 @@ object NetworkApi : BaseNetworkApi<INetworkService>(INetworkService.BASE_URL) {
service.getHistoryByDay(deviceId, fromTime, toTime)
}
/**
* 获取设备进出围栏历史数据
*/
suspend fun getHistoryFenceList(deviceId: String, fromTime: Long, toTime: Long) = getResult {
service.getHistoryFenceList(deviceId, fromTime, toTime)
}
/**
* 设置运动目标
*/
@@ -1166,11 +1173,18 @@ object NetworkApi : BaseNetworkApi<INetworkService>(INetworkService.BASE_URL) {
service.getSubscriptionsHistory(userId, deviceId)
}
/**
* 获取设备充值得的历史记录(包括自动续订)
*/
suspend fun getHistoryIncludeRenew(subscriptionId: String) = getResult {
service.getHistoryIncludeRenew(subscriptionId)
}
/**
* 获取设备充值得的历史记录
*/
suspend fun commitRefund(
currency_code: String,
currencyCode: String,
orderId: String,
chargeId: String,
amount: Int,
@@ -1182,7 +1196,7 @@ object NetworkApi : BaseNetworkApi<INetworkService>(INetworkService.BASE_URL) {
payType: Int
) = getResult {
service.commitRefund(
currency_code,
currencyCode,
orderId,
chargeId,
amount,

View File

@@ -46,7 +46,7 @@ import com.abbidot.tracker.ui.activity.device.AddNewTracker1Activity
import com.abbidot.tracker.ui.activity.device.MyTrackerV2Activity
import com.abbidot.tracker.ui.fragment.account.AccountV2Fragment
import com.abbidot.tracker.ui.fragment.data.ActivityV2Fragment
import com.abbidot.tracker.ui.fragment.data.RouteV2Fragment
import com.abbidot.tracker.ui.fragment.data.RouteV3Fragment
import com.abbidot.tracker.ui.fragment.map.MapV3Fragment
import com.abbidot.tracker.ui.fragment.pet.PetV2Fragment
import com.abbidot.tracker.util.SocketUtilManage
@@ -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
@@ -111,7 +110,7 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
private val mFragments = mutableListOf<Fragment>(
ActivityV2Fragment.newInstance(this),
RouteV2Fragment.newInstance(this),
RouteV3Fragment.newInstance(this),
MapV3Fragment.newInstance(this),
PetV2Fragment.newInstance(this),
AccountV2Fragment.newInstance(this)
@@ -212,10 +211,11 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(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 { _, allGranted ->
.request { _, deniedList ->
val allGranted = deniedList.isEmpty()
if (allGranted) {
EasyPhotos.preLoad(this)
// {
@@ -310,7 +310,7 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
//蓝牙连接就去连接socket
// mBleReportManage.dealBleReportData(macID, null)
} else {
mLogBleReportViewModel.uploadLog(mContext, macID)
mLogBleReportViewModel.uploadLog(mContext, macID, deviceOutId)
startCountDownConBle(15)
}
}
@@ -454,13 +454,13 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
packageUnavailableState()
//刚开始打开APP上传日志
getPet(false)?.apply {
mLogBleReportViewModel.uploadLog(mContext, macID)
mLogBleReportViewModel.uploadLog(mContext, macID, deviceOutId)
}
} else {
onChangeClick(mSelectPetPosition)
when (mViewBinding.homeV2ViewPager2.currentItem) {
0 -> {
(mFragments[1] as RouteV2Fragment).setNeedUpdateTag()
(mFragments[1] as RouteV3Fragment).setNeedUpdateTag()
(mFragments[3] as PetV2Fragment).setNeedUpdateTag()
}
@@ -471,13 +471,13 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
2, 4 -> {
(mFragments[0] as ActivityV2Fragment).setNeedUpdateTag()
(mFragments[1] as RouteV2Fragment).setNeedUpdateTag()
(mFragments[1] as RouteV3Fragment).setNeedUpdateTag()
(mFragments[3] as PetV2Fragment).setNeedUpdateTag()
}
3 -> {
(mFragments[0] as ActivityV2Fragment).setNeedUpdateTag()
(mFragments[1] as RouteV2Fragment).setNeedUpdateTag()
(mFragments[1] as RouteV3Fragment).setNeedUpdateTag()
}
}
}
@@ -573,7 +573,7 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
private fun checkPermissions() {
val checkBleOpen = MMKVUtil.getBoolean(MMKVKey.isFirstCheckBleOpen, true)
if (checkBleOpen) MMKVUtil.putBoolean(MMKVKey.isFirstCheckBleOpen, false)
Util.checkBluetoothPermissionsEnabled(mContext, {
Util.checkBluetoothPermissionsEnabled(this, {
// mAutomaticConnectionDeviceViewModel.autoConnectBleDevice(mContext)
}, isCheckBleOpen = checkBleOpen)
}
@@ -638,7 +638,7 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
fun refreshLocationBtnState() {
when (mViewBinding.homeV2ViewPager2.currentItem) {
0 -> (mFragments[0] as ActivityV2Fragment).checkNotifyLocationState()
1 -> (mFragments[1] as RouteV2Fragment).checkNotifyLocationState()
1 -> (mFragments[1] as RouteV3Fragment).checkNotifyLocationState()
3 -> (mFragments[3] as PetV2Fragment).checkNotifyLocationState()
}
}
@@ -654,7 +654,7 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
mChangePetListDialogAdapter.setSelectPetPos(mSelectPetPosition)
when (mViewBinding.homeV2ViewPager2.currentItem) {
0 -> (mFragments[0] as ActivityV2Fragment).showPetNameAndHead(position)
1 -> (mFragments[1] as RouteV2Fragment).showPetNameAndHead(position)
1 -> (mFragments[1] as RouteV3Fragment).showPetNameAndHead(position)
2 -> (mFragments[2] as MapV3Fragment).showPetNameAndHead(position)
3 -> (mFragments[3] as PetV2Fragment).showPetNameAndHead(position)
}

View File

@@ -35,10 +35,9 @@ 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.*
import java.util.Calendar
/**
@@ -179,7 +178,7 @@ class SplashActivity : QMUIActivity() {
// }, 600)
// }
mViewBinding.splashLogoIv.visibility = View.VISIBLE
mCountDownTimerViewModel.startCountDown(2)
mCountDownTimerViewModel.startCountDown(1)
init()
}
@@ -219,9 +218,9 @@ class SplashActivity : QMUIActivity() {
initMapbox()
}
val buglyKey = Util.getMetadata(applicationContext, KeyNames.BUG_LY_KEY_NAME)
//腾讯bugly初始化
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() {

View File

@@ -7,6 +7,7 @@ import coil.transform.BlurTransformation
import com.abbidot.baselibrary.util.LogUtil
import com.abbidot.tracker.R
import com.abbidot.tracker.base.BaseActivity
import com.abbidot.tracker.constant.ConstantInt
import com.abbidot.tracker.databinding.ActivityAddEmailValidBinding
import com.abbidot.tracker.ui.fragment.account.EmailValidFragment
@@ -31,7 +32,7 @@ open class AddEmailValidActivity :
ivForgotPasswordV2BlurBg.load(R.drawable.icon_login_v2_bg) {
transformations(BlurTransformation(mContext, 25f))
}
setListenKeyboardChange(750)
setListenKeyboardChange(750, methodType = ConstantInt.Type1)
}
switchFragment(mIndex)

View File

@@ -10,6 +10,7 @@ import com.abbidot.tracker.base.BaseActivity
import com.abbidot.tracker.base.BaseDialog
import com.abbidot.tracker.constant.GetResultCallback
import com.abbidot.tracker.databinding.ActivityEmailAddressBinding
import com.abbidot.tracker.util.Util
import com.abbidot.tracker.util.ViewUtil
import com.abbidot.tracker.vm.UserProfileViewModel
@@ -25,7 +26,7 @@ class EmailAddressActivity :
setTopBarTitle(R.string.txt_email_address)
mViewBinding.apply {
setOnClickListenerViews(btnEmailAddressChange)
setOnClickListenerViews(btnEmailAddressChange, tvEmailAddressShow)
}
}
@@ -66,6 +67,9 @@ class EmailAddressActivity :
mViewBinding.apply {
when (v!!) {
btnEmailAddressChange -> startChange()
tvEmailAddressShow -> Util.copyToClipboard(
mContext, tvEmailAddressShow.text.toString()
)
}
}
}

View File

@@ -91,7 +91,7 @@ class NotificationV2Activity :
}
}
override fun onErrorCode() {
override fun onInterceptCode() {
mPullAction?.let { p ->
mViewBinding.ilNotificationV2MessageLayout.pullRefreshAndLoadMoreLayout.finishActionRun(
p

View File

@@ -174,9 +174,7 @@ class MoreActivityActivity :
tvMoreActivityGoal.text =
String.format(getString(R.string.txt_min_unit_lower), "$activeMin/$goal")
var goalPercent = activeMin / goal.toFloat()
if (goalPercent > 1) {
goalPercent = 1f
}
goalPercent = Utils.formatDecimal(goalPercent, 2).toFloat()
goalPercent *= 100
ViewUtil.instance.viewNumberValueAnimator(
tvMoreActivityGoalPercent,
@@ -324,7 +322,7 @@ class MoreActivityActivity :
)
}
}
}, calenderShowTimestamp = cTimestamp, minLastDayRange = 364)
}, calenderShowTimestamp = cTimestamp, minLastDayRange = 29)
calenderDialog.show()
}

View File

@@ -201,7 +201,7 @@ class MoreSleepActivity :
)
}
}
}, calenderShowTimestamp = cTimestamp, minLastDayRange = 364)
}, calenderShowTimestamp = cTimestamp, minLastDayRange = 29)
calenderDialog.show()
}

View File

@@ -111,7 +111,7 @@ class SharePetActivityActivity :
//先设置文件fileProvider
EasyPhotos.createCamera(this@SharePetActivityActivity, false)
.setFileProviderAuthority("${BuildConfig.APPLICATION_ID}.fileprovider")
.setFileProviderAuthority(FileUtil.FILE_PROVIDER)
mTakePhotoAndCompressViewModel.registerCropImageActivityResult(this, 3, 4)
}

View File

@@ -92,7 +92,7 @@ class AddNewTracker1Activity :
* 检查获取定位蓝牙权限
*/
private fun checkPermissions() {
Util.checkBluetoothPermissionsEnabled(mContext, {
Util.checkBluetoothPermissionsEnabled(this, {
val intent = Intent(mContext, AddNewTracker3Activity::class.java)
intent.putExtra(ConstantString.isFirstBind, isFirstBind)
startActivity(intent)

View File

@@ -49,7 +49,7 @@ class AddNewTracker2Activity :
}
}
Util.checkBluetoothPermissionsEnabled(mContext, {
Util.checkBluetoothPermissionsEnabled(this, {
startScanBle()
})
}

View File

@@ -96,6 +96,7 @@ class AddNewTracker3Activity :
//接收蓝牙连接状态
XEventBus.observe(this, EventName.ConnectDeviceState) { ble: BleTrackDeviceBean ->
if (mConBleMac == ble.mac) {
mViewBinding.ivAddNewTracker3RefreshBtn.isEnabled = true
if (ble.conState == ConState.CONNECTED) {
setNoConnectState()
val intent = Intent(mContext, AddPairedSuccessActivity::class.java)
@@ -107,9 +108,6 @@ class AddNewTracker3Activity :
startActivity(intent)
} else if (ble.conState == ConState.CONNECTION_FAIL) {
setNoConnectState()
mViewBinding.ivAddNewTracker3RefreshBtn.isEnabled = true
} else {
mViewBinding.ivAddNewTracker3RefreshBtn.isEnabled = true
}
}
}
@@ -137,8 +135,8 @@ class AddNewTracker3Activity :
}
}
override fun onErrorCode() {
super.onErrorCode()
override fun onInterceptCode() {
super.onInterceptCode()
mViewBinding.ivAddNewTracker3RefreshBtn.isEnabled = true
setNoConnectState()
}

View File

@@ -51,6 +51,8 @@ class AddPairedSuccessActivity :
private var mDeviceOutId = ""
private var mDeviceId = ""
private var mMac = ""
//设备类型
private var mType = ConstantInt.Type1
private var mPetBean: PetBean? = null
@@ -136,6 +138,7 @@ class AddPairedSuccessActivity :
val intent = Intent(mContext, SubscriptionPlanActivity::class.java)
intent.putExtra(ConstantString.LkSetMeal, mSubscriptionsOrderBean)
intent.putExtra(ConstantString.Type, mType)
intent.putExtra(ConstantString.isFirstBind, isFirstBind)
startActivityFinish(intent)
}
@@ -187,6 +190,7 @@ class AddPairedSuccessActivity :
pet.petType = ConstantInt.DogPetType
pet.gender = ConstantInt.WoMan
pet.macID = mMac
pet.deviceType = mType
pet.birthdayDate = "2024-01-01"
pet.height = Utils.formatDecimal(Util.inToCm(20.0), 1).toFloat()
pet.weight = Utils.formatDecimal(Util.lbsToKg(25.0), 1).toFloat()
@@ -348,6 +352,13 @@ class AddPairedSuccessActivity :
}
}
override fun leftBackOnClick() {
if (!TextUtils.isEmpty(mMac)) {
SRBleUtil.instance.disconnectToMac(mMac)
}
super.leftBackOnClick()
}
override fun onClick(v: View?) {
mViewBinding.apply {
when (v!!) {

View File

@@ -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")
@@ -181,6 +184,7 @@ open class AddAndEditFencesZoneBaseActivity :
rlAddEditFencesZoneInfoLayout.setOnTouchListener { v, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> {
hideInputMethod(v)
oldY = event.y
}
@@ -188,10 +192,12 @@ open class AddAndEditFencesZoneBaseActivity :
}
MotionEvent.ACTION_UP -> {
if (event.y - oldY > slideDis) {
downLayout()
} else if (event.y - oldY < -slideDis) {
slideUpLayout()
if (!isKeyboardTranslate) {
if (event.y - oldY > slideDis) {
downLayout()
} else if (event.y - oldY < -slideDis) {
slideUpLayout()
}
}
}
}
@@ -203,11 +209,16 @@ open class AddAndEditFencesZoneBaseActivity :
}
}
setListenKeyboardChange()
setListenKeyboardChange(methodType = ConstantInt.Type1)
setFenceName()
}
override fun leftBackOnClick() {
if (isBlockedClick) return
super.leftBackOnClick()
}
open fun mapLoadOk() {
drawFences()
}
@@ -355,7 +366,7 @@ open class AddAndEditFencesZoneBaseActivity :
override fun onRequestError(exceptionCode: String?) {
super.onRequestError(exceptionCode)
setButtonEnabled(mViewBinding.btnSaveFencesZone, ConstantInt.Type1)
setDisableState(false)
}
})
}
@@ -373,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) {
@@ -388,7 +404,7 @@ open class AddAndEditFencesZoneBaseActivity :
override fun onRequestError(exceptionCode: String?) {
super.onRequestError(exceptionCode)
setButtonEnabled(mViewBinding.btnSaveFencesZone, ConstantInt.Type1)
setDisableState(false)
}
})
}
@@ -413,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()
@@ -656,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 -> {
@@ -684,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()
@@ -743,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
@@ -881,7 +917,7 @@ open class AddAndEditFencesZoneBaseActivity :
}
tvFencesZoneShapeResetBtn -> recoverDefaultFencesView()
btnCancelFencesZone -> finish()
btnCancelFencesZone -> if (!isBlockedClick) finish()
ivFencesZoneMapSwitchBtn -> switchMapType()
}
}

View File

@@ -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,7 +417,8 @@ class PreviewFencesZoneActivity :
}
private fun goEditFences() {
Util.checkLocationPermissionsGpsEnabled(mContext, {
if (isBlockedClick) return
Util.checkLocationPermissionsGpsEnabled(this, {
mCurrentFences?.apply {
val intent = if (fenceType == ConstantInt.SafeZone) Intent(
mContext, EditSafeZoneActivity::class.java
@@ -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()

View File

@@ -338,7 +338,7 @@ class VirtualFencesActivity :
}
private fun goPreviewFencesZone(fencesBean: FencesBean) {
Util.checkLocationPermissionsGpsEnabled(mContext, {
Util.checkLocationPermissionsGpsEnabled(this, {
mPetBean?.apply {
val intent = Intent(mContext, PreviewFencesZoneActivity::class.java)
intent.putExtra(ConstantString.Fence, fencesBean)
@@ -351,7 +351,7 @@ class VirtualFencesActivity :
private fun goAddSafeZone() {
val share = MMKVUtil.getInt(MMKVKey.Shared)
if (share != ConstantInt.NoShare) return
Util.checkLocationPermissionsGpsEnabled(mContext, {
Util.checkLocationPermissionsGpsEnabled(this, {
val intent = Intent(mContext, AddSafeZoneActivity::class.java)
intent.putExtra(ConstantString.Pet, mPetBean)
intent.putExtra(ConstantString.Fence, mGetFencesBean)
@@ -362,7 +362,7 @@ class VirtualFencesActivity :
private fun goAddNoGoZone() {
val share = MMKVUtil.getInt(MMKVKey.Shared)
if (share != ConstantInt.NoShare) return
Util.checkLocationPermissionsGpsEnabled(mContext, {
Util.checkLocationPermissionsGpsEnabled(this, {
val intent = Intent(mContext, AddNoGoZoneActivity::class.java)
intent.putExtra(ConstantString.Pet, mPetBean)
intent.putExtra(ConstantString.Fence, mGetFencesBean)

View File

@@ -159,7 +159,7 @@ class LedLightActivity : BaseActivity<ActivityLedLightBinding>(ActivityLedLightB
setLedControlState()
}
override fun onErrorCode() {
override fun onInterceptCode() {
setLedControlState()
}
})
@@ -177,7 +177,7 @@ class LedLightActivity : BaseActivity<ActivityLedLightBinding>(ActivityLedLightB
setLedModeControlState()
}
override fun onErrorCode() {
override fun onInterceptCode() {
setLedModeControlState()
}
})
@@ -279,8 +279,8 @@ class LedLightActivity : BaseActivity<ActivityLedLightBinding>(ActivityLedLightB
private fun setDeviceData(mapDeviceBean: MapDeviceBean) {
mapDeviceBean.apply {
mLedMode=ledMode
mLedSwitch=ledSwitch
mLedMode = ledMode
mLedSwitch = ledSwitch
mViewBinding.let {
it.ledLightOpenAndClose.switch.isChecked = ledSwitch == ConstantInt.Open
@@ -343,7 +343,7 @@ class LedLightActivity : BaseActivity<ActivityLedLightBinding>(ActivityLedLightB
if (BleManager.getInstance().isConnected(deviceMacId)) {
//蓝牙控制
SRBleUtil.instance.getConnectMacDevice(deviceMacId)?.let {
SRBleUtil.instance.setBleLedSwitch(mContext, it.bleDevice, mode)
SRBleUtil.instance.setBleLedSwitch(this@LedLightActivity, it.bleDevice, mode)
}
} else {
//远程控制
@@ -373,8 +373,10 @@ class LedLightActivity : BaseActivity<ActivityLedLightBinding>(ActivityLedLightB
if (ilLedLightIssueLayout.root.isGone) {
YoYo.with(Techniques.BounceInUp).duration(700).onStart {
ilLedLightIssueLayout.root.visibility = View.VISIBLE
vLedIssueShadeView.visibility = View.VISIBLE
}.playOn(ilLedLightIssueLayout.root)
} else {
vLedIssueShadeView.visibility = View.GONE
YoYo.with(Techniques.SlideOutDown).duration(600).onEnd {
ilLedLightIssueLayout.root.visibility = View.GONE
}.playOn(ilLedLightIssueLayout.root)
@@ -414,7 +416,9 @@ class LedLightActivity : BaseActivity<ActivityLedLightBinding>(ActivityLedLightB
if (BleManager.getInstance().isConnected(deviceMacId)) {
//蓝牙控制
SRBleUtil.instance.getConnectMacDevice(deviceMacId)?.let {
SRBleUtil.instance.setBleLedSwitch(mContext, it.bleDevice, ledSwitch)
SRBleUtil.instance.setBleLedSwitch(
this@LedLightActivity, it.bleDevice, ledSwitch
)
}
} else {
//远程控制

View File

@@ -245,7 +245,7 @@ class LedLightActivityV0 : BaseActivity<ActivityLedLightBinding>(ActivityLedLigh
setDisabledState(false)
} else {
//是否超时上报
val isTimeoutReport = Util.isTimeoutReport(updateTime)
val isTimeoutReport = Util.isTimeoutReport(updateTime,gnssInterval)
if (powerSwitch == ConstantInt.Type0 || powerSwitch == ConstantInt.Type2 || powerSwitch == ConstantInt.Type3 || inWifiZone == ConstantInt.Type1 || isTimeoutReport) {
setDisabledState(true)
} else {
@@ -294,7 +294,7 @@ class LedLightActivityV0 : BaseActivity<ActivityLedLightBinding>(ActivityLedLigh
private fun setBleLedMode(mode: Int) {
mBleTrackDeviceBean?.apply {
SRBleUtil.instance.setBleLedSwitch(mContext, bleDevice, mode)
SRBleUtil.instance.setBleLedSwitch(this@LedLightActivityV0, bleDevice, mode)
}
}

View File

@@ -273,7 +273,7 @@ class AddWifiPasswordActivity :
}
private fun goEditWifiActivity() {
Util.checkLocationPermissionsGpsEnabled(mContext, {
Util.checkLocationPermissionsGpsEnabled(this, {
val intent = Intent(mContext, EditWifiPowerZoneActivity::class.java)
intent.putExtra(ConstantString.WiFi, mWiFiBean)
mDecWiFiAddressData?.let {

Some files were not shown because too many files have changed in this diff Show More