Compare commits

..

18 Commits

Author SHA1 Message Date
yezhiqiu
ca554656c5 1.订阅套餐新ui:增加套餐描述;修改价格区底色;Best 用皇冠图标代替;
2.新增Initializing Device界面
3.校对新增多语言字符
2026-05-14 17:14:58 +08:00
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
213 changed files with 3796 additions and 742 deletions

View File

@@ -4,10 +4,10 @@
<selectionStates> <selectionStates>
<SelectionState runConfigName="app"> <SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" /> <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"> <Target type="DEFAULT_BOOT">
<handle> <handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=3A040DLJH000R0" /> <DeviceId pluginId="PhysicalDevice" identifier="serial=R5CT80BHT3Y" />
</handle> </handle>
</Target> </Target>
</DropdownSelection> </DropdownSelection>

View File

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

View File

@@ -1 +1 @@
#Wed Apr 08 14:56:42 CST 2026 #Tue Apr 21 16:52:55 CST 2026

View File

@@ -28,9 +28,9 @@ android {
applicationId "com.abbidot.tracker" applicationId "com.abbidot.tracker"
minSdkVersion 23 minSdkVersion 23
targetSdkVersion 35 targetSdkVersion 35
versionCode 2113 versionCode 2205
// versionName "2.1.13" // versionName "2.2.5"
versionName "2.1.13-Beta3" versionName "2.2.5-Beta1"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 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文件 // 读取local.properties文件
Properties properties = new Properties() Properties properties = new Properties()
InputStream inputStream = project.rootProject.file('local.properties').newDataInputStream() InputStream inputStream = project.rootProject.file('local.properties').newDataInputStream()
@@ -182,29 +193,32 @@ dependencies {
// implementation 'com.google.android.material:material:1.10.0' // implementation 'com.google.android.material:material:1.10.0'
// implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" // implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.10.0'
implementation 'androidx.activity:activity:1.8.0'
testImplementation 'junit:junit:4.13.2' testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.2.1' androidTestImplementation 'androidx.test.ext:junit:1.2.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1'
// Android官方库 // 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-common:2.2.0'
implementation 'androidx.arch.core:core-runtime:2.2.0' implementation 'androidx.arch.core:core-runtime:2.2.0'
implementation 'androidx.activity:activity-ktx:1.9.3' implementation 'androidx.activity:activity-ktx:1.10.1'
implementation 'androidx.fragment:fragment-ktx:1.5.6' implementation 'androidx.fragment:fragment-ktx:1.8.9'
implementation 'androidx.annotation:annotation:1.9.1' implementation 'androidx.annotation:annotation:1.10.0'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.8.7' implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.10.0'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.8.7' implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.10.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.7' 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-rxjava2:2.3.0'
implementation 'androidx.room:room-ktx:2.5.2' implementation 'androidx.room:room-ktx:2.8.4'
kapt 'androidx.room:room-compiler:2.5.2' kapt 'androidx.room:room-compiler:2.8.4'
//hilt依赖注入https://mvnrepository.com/artifact/com.google.dagger/hilt-android-gradle-plugin //hilt依赖注入https://mvnrepository.com/artifact/com.google.dagger/hilt-android-gradle-plugin
implementation "com.google.dagger:hilt-android:2.57" implementation "com.google.dagger:hilt-android:2.57.2"
kapt "com.google.dagger:hilt-android-compiler:2.57" kapt "com.google.dagger:hilt-android-compiler:2.57.2"
//Android UI 开发效率的 UI 库https://github.com/Tencent/QMUI_Android //Android UI 开发效率的 UI 库https://github.com/Tencent/QMUI_Android
implementation 'com.qmuiteam:qmui:2.1.0' implementation 'com.qmuiteam:qmui:2.1.0'
@@ -221,11 +235,11 @@ dependencies {
implementation "io.coil-kt:coil-gif:1.4.0"//支持GIF implementation "io.coil-kt:coil-gif:1.4.0"//支持GIF
//lottie动画https://github.com/airbnb/lottie-android //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 //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 //升级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' implementation 'com.google.android.gms:play-services-maps:20.0.0'
@@ -245,21 +259,24 @@ dependencies {
//mapbox地图https://github.com/mapbox/mapbox-maps-android //mapbox地图https://github.com/mapbox/mapbox-maps-android
// implementation 'com.mapbox.maps:android:10.2.0' // implementation 'com.mapbox.maps:android:10.2.0'
//https://github.com/mapbox/mapbox-search-android //https://github.com/mapbox/mapbox-search-android
//用mapbox搜索SDK,地理编码 有搜索ui组件已包括mapbox-search-android架包 /**用mapbox搜索SDK,地理编码 有搜索ui组件已包括mapbox-search-android架包
implementation "com.mapbox.search:mapbox-search-android-ui:2.5.1" * 支持 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组件 // mapbox搜索SDK,地理编码 没有搜索ui组件
// implementation "com.mapbox.search:mapbox-search-android:1.0.0-beta.25" // implementation "com.mapbox.search:mapbox-search-android:1.0.0-beta.25"
//用于计算距离https://docs.mapbox.com/android/java/guides/turf/#available-methods //用于计算距离https://docs.mapbox.com/android/java/guides/#installation
implementation 'com.mapbox.mapboxsdk:mapbox-sdk-turf:6.15.0' implementation 'com.mapbox.mapboxsdk:mapbox-sdk-turf:7.10.0'
//用于计算路线规划信息https://docs.mapbox.com/android/java/examples/dashed-directions-line/ //用于计算路线规划信息、地理编码
implementation 'com.mapbox.mapboxsdk:mapbox-sdk-services:6.3.0' implementation 'com.mapbox.mapboxsdk:mapbox-sdk-services:7.10.0'
// 权限请求框架https://github.com/getActivity/XXPermissions // 权限请求框架https://github.com/getActivity/XXPermissions
implementation 'com.github.getActivity:XXPermissions:25.2' implementation 'com.github.getActivity:XXPermissions:28.2'
// 吐司框架https://github.com/getActivity/ToastUtils // 吐司框架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模式下集成 // 日志调试框架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 // PictureSelector图片选择器,需要compileSdkVersion=31 https://github.com/LuckSiege/PictureSelector
// implementation 'io.github.lucksiege:pictureselector:v3.0.3' // implementation 'io.github.lucksiege:pictureselector:v3.0.3'
@@ -268,14 +285,14 @@ dependencies {
//压缩图片 https://github.com/zetbaitsu/Compressor //压缩图片 https://github.com/zetbaitsu/Compressor
implementation 'id.zelory:compressor:3.0.1' implementation 'id.zelory:compressor:3.0.1'
//图片裁剪功能https://github.com/CanHub/Android-Image-Cropper //图片裁剪功能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***************************************************** //******************************************极光推送start*****************************************************
// https://docs.jiguang.cn/jpush/client/Android/android_guide // 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:jcore:3.1.2' // 此处以JCore 2.7.2 版本为例。
// implementation 'cn.jiguang.sdk:jpush:4.6.0' // 此处以JPush 4.0.0 版本为例 // 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:jcore-google:5.3.7' // 此处以JCore 2.7.2 版本为例。
implementation 'cn.jiguang.sdk:jpush-google:5.8.0' // 此处以JPush 4.0.0 版本为例 implementation 'cn.jiguang.sdk:jpush-google:6.0.7' // 此处以JPush 4.0.0 版本为例
// 接入华为厂商 // 接入华为厂商
// implementation 'com.huawei.hms:push:6.1.0.300' // implementation 'com.huawei.hms:push:6.1.0.300'
// implementation 'cn.jiguang.sdk.plugin:huawei:4.0.0'// 极光厂商插件版本与接入 JPush 版本保持一致,下同 // implementation 'cn.jiguang.sdk.plugin:huawei:4.0.0'// 极光厂商插件版本与接入 JPush 版本保持一致,下同
@@ -294,7 +311,7 @@ dependencies {
//******************************************极光推送end******************************************************* //******************************************极光推送end*******************************************************
//其中指代最新Bugly SDK版本号也可以指定明确的版本号例如4.0.0 //其中指代最新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 //其中latest.release指代最新Bugly NDK版本号也可以指定明确的版本号例如3.9.2
// implementation 'com.tencent.bugly:nativecrashreport:3.9.2' // implementation 'com.tencent.bugly:nativecrashreport:3.9.2'
@@ -306,24 +323,27 @@ dependencies {
implementation 'com.stripe:stripe-android:20.27.0' 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.tencent.mm.opensdk:wechat-sdk-android:+'
//支付宝支付 //支付宝支付
implementation 'com.alipay.sdk:alipaysdk-android:+@aar' implementation 'com.alipay.sdk:alipaysdk-android:+@aar'
//dfu升级https://github.com/NordicSemiconductor/Android-DFU-Library //g30 dfu升级https://github.com/NordicSemiconductor/Android-DFU-Library
implementation 'no.nordicsemi.android:dfu:2.9.0' 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启动动画闪屏图片 //适配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 //优雅、万能自定义日历https://github.com/huanghaibin-dev/CalendarView
// implementation 'com.haibin:calendarview:3.7.1' // implementation 'com.haibin:calendarview:3.7.1'
//https://github.com/angcyo/CalendarView //https://github.com/angcyo/CalendarView

View File

@@ -38,6 +38,7 @@
<uses-permission <uses-permission
android:name="android.permission.WRITE_SETTINGS" android:name="android.permission.WRITE_SETTINGS"
tools:ignore="ProtectedPermissions" /> <!-- android 9.0上使用前台服务,需要添加权限 --> tools:ignore="ProtectedPermissions" /> <!-- android 9.0上使用前台服务,需要添加权限 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <!-- BLUETOOTH permissions are added by lib_dfu module. -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <!-- 用于读取手机当前的状态 --> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <!-- 用于读取手机当前的状态 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!-- 读取缓存数据 --> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!-- 读取缓存数据 -->
<!-- 蓝牙扫描权限 --> <!-- 蓝牙扫描权限 -->
@@ -55,7 +56,6 @@
android:protectionLevel="signature" /> <!-- Optional. Required for location feature --> android:protectionLevel="signature" /> <!-- Optional. Required for location feature -->
<uses-permission android:name="${applicationId}.permission.JPUSH_MESSAGE" /> <!-- 为了提高sdk识别唯一用户的能力保证消息推送的精准送达建议集成以下权限可选 --> <uses-permission android:name="${applicationId}.permission.JPUSH_MESSAGE" /> <!-- 为了提高sdk识别唯一用户的能力保证消息推送的精准送达建议集成以下权限可选 -->
<!-- <uses-permission --> <!-- <uses-permission -->
<!-- android:name="android.permission.QUERY_ALL_PACKAGES" -->
<!-- tools:ignore="QueryAllPackagesPermission" /> --> <!-- tools:ignore="QueryAllPackagesPermission" /> -->
<!-- 如您需要接入地理围栏业务,建议集成以下权限(可选) --> <!-- 如您需要接入地理围栏业务,建议集成以下权限(可选) -->
<uses-permission android:name="android.permission.GET_TASKS" /> <!-- 如您需要对应设备通知相关的能力,建议集成以下权限(可选) --> <uses-permission android:name="android.permission.GET_TASKS" /> <!-- 如您需要对应设备通知相关的能力,建议集成以下权限(可选) -->
@@ -86,8 +86,7 @@
android:name="android.permission.BLUETOOTH_SCAN" android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation" android:usesPermissionFlags="neverForLocation"
tools:targetApi="s" /> tools:targetApi="s" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <!-- BLUETOOTH permissions are added by lib_dfu module. --> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" /> <!-- 指定微信包名 --> <uses-permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" /> <!-- 指定微信包名 -->
<queries> <queries>
<package android:name="com.tencent.mm" /> <package android:name="com.tencent.mm" />
@@ -106,6 +105,9 @@
android:usesCleartextTraffic="true" android:usesCleartextTraffic="true"
tools:replace="android:supportsRtl" tools:replace="android:supportsRtl"
tools:targetApi="n"> tools:targetApi="n">
<activity
android:name=".ui.activity.device.InitializingDeviceActivity"
android:exported="false" />
<activity <activity
android:name=".ui.activity.device.set.PowerOffActivity" android:name=".ui.activity.device.set.PowerOffActivity"
android:exported="false" android:exported="false"
@@ -386,7 +388,8 @@
<activity <activity
android:name=".ui.activity.device.wifi.EditWifiPowerZoneActivity" android:name=".ui.activity.device.wifi.EditWifiPowerZoneActivity"
android:exported="false" android:exported="false"
android:screenOrientation="portrait" /> android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan" />
<activity <activity
android:name=".ui.activity.map.LiveActivityV3" android:name=".ui.activity.map.LiveActivityV3"
android:exported="false" android:exported="false"

View File

@@ -2,19 +2,50 @@
<body> <body>
<div> <div>
<h3>ABBIDOT Tracker Subscription Terms and Conditions <h2>ABBIDOT Tracker Subscription Terms and Conditions</h2>
</h3> <hr>
<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. <h3>1. Subscription Plans</h3>
<p>ABBIDOT offers three subscription plans:</p>
<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> <ul>
<li>3-Month Plan</li>
<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> <li>1-Year Plan</li>
<li>2-Year Plan</li>
<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> </ul>
<p>All subscriptions are automatically renewed at the end of each billing cycle unless canceled by the user.</p>
<p>For support contact:</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>support@abbidot.com</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> </div>

View File

@@ -1,7 +1,11 @@
package com.abbidot.tracker.adapter package com.abbidot.tracker.adapter
import android.content.Context import android.content.Context
import android.content.res.ColorStateList
import android.text.TextUtils
import android.view.View import android.view.View
import androidx.core.content.ContextCompat
import androidx.core.graphics.toColorInt
import com.abbidot.baselibrary.list.BaseRecyclerAdapter import com.abbidot.baselibrary.list.BaseRecyclerAdapter
import com.abbidot.baselibrary.list.RecyclerViewHolder import com.abbidot.baselibrary.list.RecyclerViewHolder
import com.abbidot.baselibrary.util.Utils import com.abbidot.baselibrary.util.Utils
@@ -9,6 +13,8 @@ import com.abbidot.tracker.R
import com.abbidot.tracker.bean.PackageBean import com.abbidot.tracker.bean.PackageBean
import com.abbidot.tracker.constant.ConstantInt import com.abbidot.tracker.constant.ConstantInt
import com.abbidot.tracker.constant.ConstantString import com.abbidot.tracker.constant.ConstantString
import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundButtonDrawable
import com.qmuiteam.qmui.widget.roundwidget.QMUIRoundRelativeLayout
/** /**
*Created by .yzq on 2024/8/6/006. *Created by .yzq on 2024/8/6/006.
@@ -51,6 +57,10 @@ class ChoosePlanAdapter(
getView(R.id.ll_choose_plan_item_discount_percent).let { getView(R.id.ll_choose_plan_item_discount_percent).let {
it.visibility = if (item.popularType == ConstantInt.Type1) View.INVISIBLE
else View.INVISIBLE
}
getView(R.id.iv_choose_plan_item_popular_image).let {
it.visibility = if (item.popularType == ConstantInt.Type1) View.VISIBLE it.visibility = if (item.popularType == ConstantInt.Type1) View.VISIBLE
else View.INVISIBLE else View.INVISIBLE
} }
@@ -62,6 +72,44 @@ class ChoosePlanAdapter(
if (item.popularType == ConstantInt.Type1) it.visibility = View.GONE if (item.popularType == ConstantInt.Type1) it.visibility = View.GONE
else it.visibility = View.GONE else it.visibility = View.GONE
} }
(getView(R.id.rl_choose_plan_item_price) as QMUIRoundRelativeLayout).let {
(it.background as QMUIRoundButtonDrawable).let { drawable ->
val bgColor = if (TextUtils.isEmpty(item.bottomBgColor)) {
ContextCompat.getColor(mContext, R.color.tracker_manage_bg_color)
} else {
item.bottomBgColor.toColorInt()
}
drawable.setBgData(ColorStateList.valueOf(bgColor))
}
}
getTextView(R.id.tv_choose_plan_item_power).let {
it.visibility = if (item.list.isNullOrEmpty()) View.GONE
else {
var str = getManyLanguageLimitDec(item.listTitleCode)
if (TextUtils.isEmpty(str)) {
for (i in 0 until item.list!!.size) {
val packageDec = item.list!![i]
str += "${i + 1}.${packageDec.title}"
if (i != item.list!!.size - 1) {
str += "\n"
}
}
}
it.text = str
View.VISIBLE
}
}
}
}
private fun getManyLanguageLimitDec(nameCode: Int): String {
return when (nameCode) {
ConstantInt.Type1 -> mContext.getString(R.string.txt_package_permission1)
ConstantInt.Type2 -> mContext.getString(R.string.txt_package_permission2)
ConstantInt.Type3 -> mContext.getString(R.string.txt_package_permission3)
else -> ""
} }
} }
} }

View File

@@ -1,12 +1,13 @@
package com.abbidot.tracker.adapter package com.abbidot.tracker.adapter
import android.graphics.Typeface import android.graphics.Typeface
import android.widget.ImageView import android.util.TypedValue
import androidx.appcompat.widget.AppCompatImageView import androidx.appcompat.widget.AppCompatImageView
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import com.abbidot.baselibrary.util.AppUtils import com.abbidot.baselibrary.util.AppUtils
import com.abbidot.tracker.R import com.abbidot.tracker.R
import com.abbidot.tracker.bean.MenuTxtBean import com.abbidot.tracker.bean.MenuTxtBean
import com.abbidot.tracker.constant.ConstantInt
import com.abbidot.tracker.constant.MultipleEntity import com.abbidot.tracker.constant.MultipleEntity
import com.abbidot.tracker.widget.TypefaceTextView import com.abbidot.tracker.widget.TypefaceTextView
import com.chad.library.adapter.base.BaseMultiItemQuickAdapter 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) addItemType(MultipleEntity.IMG_IMG, R.layout.layout_help_title1)
//显示14sp大小的文字内容 //显示14sp大小的文字内容
addItemType(MultipleEntity.IMG_TEXT_IMG, R.layout.layout_help_title2) 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) { 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.getView<TypefaceTextView>(R.id.tv_help_title_two).text = item.menuName
holder.itemView.setPadding(0, AppUtils.dpToPx(14), 0, 0) 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( holder.setText(
R.id.tv_my_subscription_active_time, 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 { 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 { holder.getTextView(R.id.tv_my_subscription_expires_on).apply {
text = if (item.orderStatus == 6 && item.refundTime > 0L) { 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 { } else {
Utils.formatTime( Utils.formatTime(
Utils.timestampAddHowTimestamp( Utils.timestampAddHowTimestamp(
item.payTime, item.mealPeriod, item.mealUnit 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) val times = Utils.differYear(cTimeMillis, item.endTime)
holder.setText(R.id.tv_add_success_device_expires_days, times[0]) holder.getTextView(R.id.tv_add_success_device_expires_days).apply {
holder.setText(R.id.tv_add_success_device_expires_hours, times[1]) visibility = if (item.subscriptionStatus == ConstantInt.Close) {
holder.setText(R.id.tv_add_success_device_expires_min, times[2]) 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 { holder.getView(R.id.fl_my_subscription_btn_layout).apply {
//UserId不一样就是共享设备的订单 //UserId不一样就是共享设备的订单
@@ -187,7 +205,7 @@ class MySubscriptionAdapter(
setOnClickListener { setOnClickListener {
qMUIPopups.dismiss() qMUIPopups.dismiss()
Intent(mContext, SubscriptionHistoryActivity::class.java).let { Intent(mContext, SubscriptionHistoryActivity::class.java).let {
it.putExtra(ConstantString.DeviceId, item.deviceId) it.putExtra(ConstantString.Id, item.subscriptionId)
mMySubscriptionActivity.startActivity(it) mMySubscriptionActivity.startActivity(it)
} }
} }

View File

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

View File

@@ -1,5 +1,6 @@
package com.abbidot.tracker.adapter package com.abbidot.tracker.adapter
import android.content.Context
import android.content.Intent import android.content.Intent
import android.view.View import android.view.View
import android.widget.TextView import android.widget.TextView
@@ -16,6 +17,8 @@ import com.abbidot.tracker.ui.activity.subscribe.SubscriptionHistoryActivity
import com.abbidot.tracker.widget.TypefaceRoundButton import com.abbidot.tracker.widget.TypefaceRoundButton
import com.chad.library.adapter.base.BaseMultiItemQuickAdapter import com.chad.library.adapter.base.BaseMultiItemQuickAdapter
import com.chad.library.adapter.base.viewholder.BaseViewHolder 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. *Created by .yzq on 2024/8/19/019.
@@ -46,6 +49,9 @@ class SubscriptionHistoryAdapter(
} }
} }
/**
* 保险订单
*/
private fun bindAnnualCareData(holder: BaseViewHolder, item: SubscriptionsOrderBean) { private fun bindAnnualCareData(holder: BaseViewHolder, item: SubscriptionsOrderBean) {
holder.setText( holder.setText(
R.id.tv_subscription_annual_care_order_id, 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_state, state)
holder.setText( holder.setText(
R.id.tv_subscription_annual_care_active_time, Utils.formatTime( 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个月算 //保险时长不足一年按12个月算
@@ -73,7 +79,7 @@ class SubscriptionHistoryAdapter(
R.id.tv_subscription_annual_care_expiry_time, Utils.formatTime( R.id.tv_subscription_annual_care_expiry_time, Utils.formatTime(
Utils.timestampAddHowTimestamp( Utils.timestampAddHowTimestamp(
item.payTime, insuranceTime, ConstantString.PackageUnitYear item.payTime, insuranceTime, ConstantString.PackageUnitYear
), Utils.DATE_FORMAT_PATTERN_EN7 ), Utils.DATE_FORMAT_PATTERN_CN
) )
) )
holder.setText( holder.setText(
@@ -93,7 +99,7 @@ class SubscriptionHistoryAdapter(
) )
holder.setText( holder.setText(
R.id.tv_subscription_history_order_time, 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(R.id.tv_subscription_history_package_name, item.mealName)
holder.setText( holder.setText(
@@ -111,33 +117,39 @@ class SubscriptionHistoryAdapter(
visibility = View.VISIBLE visibility = View.VISIBLE
when (item.orderStatus) { when (item.orderStatus) {
1 -> { 1 -> {
val updateTimestamp = Utils.stringToTimestamp(item.updateTime, isUtc = true) if (item.isAutoRenewal == ConstantInt.Type1) {
val nowTimestamp = System.currentTimeMillis()
if (item.enabled == ConstantInt.Type0 || (item.surplusDays == 0L && item.subscriptionStatus == ConstantInt.Close)) {
visibility = View.GONE 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 { } else {
visibility = View.GONE setRefundState(context, item.isRefundable, this)
} }
} else {
val day30Timestamp = 30 * 24 * 60 * 60 * 1000L // val updateTimestamp = Utils.stringToTimestamp(item.updateTime, isUtc = true)
//套餐超出30天不能退款 // val nowTimestamp = System.currentTimeMillis()
if (nowTimestamp - updateTimestamp <= day30Timestamp) { // if (item.enabled == ConstantInt.Type0 || (item.surplusDays == 0L && item.subscriptionStatus == ConstantInt.Close)) {
visibility = View.VISIBLE // visibility = View.GONE
setText(R.string.txt_refund) // } else if (item.mealUnit == ConstantString.PackageUnitDay) {
} else { // visibility = View.VISIBLE
visibility = View.GONE // setText(R.string.txt_refund)
} // } else if (item.mealUnit == ConstantString.PackageUnitMonth) {
} // val day7Timestamp = 7 * 24 * 60 * 60 * 1000L
setTextColor(ContextCompat.getColor(context, R.color.select_color)) // //套餐超出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) 4 -> setText(R.string.txt_waiting)
@@ -155,6 +167,10 @@ class SubscriptionHistoryAdapter(
setChangeAlphaWhenPress(true) setChangeAlphaWhenPress(true)
setOnClickListener { setOnClickListener {
if (item.orderStatus == ConstantInt.Type1) { 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 { Intent(context, RequestRefundActivity::class.java).apply {
putExtra(ConstantString.SetMeal, item) putExtra(ConstantString.SetMeal, item)
mHistoryActivity.startActivity(this) mHistoryActivity.startActivity(this)
@@ -166,8 +182,7 @@ class SubscriptionHistoryAdapter(
val cTimeMillis = System.currentTimeMillis() val cTimeMillis = System.currentTimeMillis()
val endTime = if (item.refundTime == 0L) item.endTime else item.refundTime val endTime = if (item.refundTime == 0L) item.endTime else item.refundTime
val expiredTime = endTime * 1000 - cTimeMillis val expiredTime = endTime * 1000 - cTimeMillis
val state = val state = if (item.enabled == ConstantInt.Type0 || (expiredTime <= 0)) {
if (item.enabled == ConstantInt.Type0 || (item.subscriptionStatus == ConstantInt.Close && expiredTime <= 0)) {
context.getString(R.string.txt_expired) context.getString(R.string.txt_expired)
} else { } else {
context.getString(R.string.txt_active) context.getString(R.string.txt_active)
@@ -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 private var mLoadingDialog: QMUITipDialog? = null
//默认删除去掉titleTopBar底部间隔下划线 //默认删除去掉titleTopBar底部间隔下划线
var mDeleteBottomDivider: Boolean = true private var mDeleteBottomDivider: Boolean = true
//Activity是否在前台显示运行 //Activity是否在前台显示运行
var isFrontRunning = false var isFrontRunning = false
@@ -86,8 +86,8 @@ abstract class BaseActivity<T : ViewBinding>(val inflater: (inflater: LayoutInfl
// 监听因输入框弹出,遮挡输入框,界面移动,需要移动的view // 监听因输入框弹出,遮挡输入框,界面移动,需要移动的view
private var mTranslateView: View? = null private var mTranslateView: View? = null
/*****************************监听软键盘弹出,输入框上移start************************************/ /*****************************监听软键盘弹出,输入框上移 ************************************/
private var isKeyboardTranslate = true var isKeyboardTranslate = true
//是否需要适配底部EdgeToEdge //是否需要适配底部EdgeToEdge
var isEdgeToEdgeAdapterNavigationBars = true var isEdgeToEdgeAdapterNavigationBars = true
@@ -168,6 +168,7 @@ abstract class BaseActivity<T : ViewBinding>(val inflater: (inflater: LayoutInfl
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()
isFrontRunning = false
//键盘隐藏恢复默认状态 //键盘隐藏恢复默认状态
mTranslateView?.apply { mTranslateView?.apply {
scrollTo(0, 0) scrollTo(0, 0)
@@ -231,15 +232,24 @@ 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 metrics = getResources().displayMetrics
val screenWidth = metrics.widthPixels val screenWidth = metrics.widthPixels
// val screenHeight = metrics.heightPixels // val screenHeight = metrics.heightPixels
val scaleFactor = screenWidth / 1080 // 假设 1080 是设计宽度 val scaleFactor = screenWidth / 1080 // 假设 1080 是设计宽度
window.decorView.viewTreeObserver.addOnGlobalLayoutListener { view.viewTreeObserver.addOnGlobalLayoutListener {
if (methodType == ConstantInt.Type0) {
onLayoutChange(view, windowTranslateY * scaleFactor) onLayoutChange(view, windowTranslateY * scaleFactor)
} else {
onGlobalLayoutChange(view, windowTranslateY * scaleFactor)
} }
} }
}
/** /**
* 设置其他包含的view点击。隐藏软键盘如ScrollView * 设置其他包含的view点击。隐藏软键盘如ScrollView
@@ -560,16 +570,24 @@ abstract class BaseActivity<T : ViewBinding>(val inflater: (inflater: LayoutInfl
val exceptionMessage = it.exceptionOrNull()?.message val exceptionMessage = it.exceptionOrNull()?.message
//服务器返回错误code //服务器返回错误code
val exceptionCode: String? = it.exceptionOrNull()?.toString() val exceptionCode: String? = it.exceptionOrNull()?.toString()
LogUtil.d("Throwable", "code=${exceptionCode},${exceptionMessage}") LogUtil.d("Throwable异常", "code=${exceptionCode},${exceptionMessage}")
if (null != exceptionCode) { if (null != exceptionCode) {
//处理注册用户已存在的情况 //处理注册用户已存在的情况
if (exceptionCode == ErrorCode.USER_HAS_EXIST.toString()) { if (exceptionCode == ErrorCode.USER_HAS_EXIST.toString()) {
getResultCallback.onRequestError(exceptionCode) 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 //拦截请求异常code
if (netErrorCodeTips(exceptionCode, isShowCodeError)) { else if (netErrorCodeTips(exceptionCode, isShowCodeError)) {
//已经处理相关错误码就直接返回 //已经处理相关错误码就直接返回
getResultCallback.onErrorCode() getResultCallback.onInterceptCode()
return return
} }
} }
@@ -675,10 +693,10 @@ abstract class BaseActivity<T : ViewBinding>(val inflater: (inflater: LayoutInfl
return true return true
} }
//该设备已被绑定 //该设备已被绑定
ErrorCode.DEVICE_HAS_BIND.toString() -> { // ErrorCode.DEVICE_HAS_BIND.toString() -> {
if (isShowCodeError) showToast(R.string.txt_device_has_bind) // if (isShowCodeError) showToast(R.string.txt_device_has_bind)
return true // return true
} // }
//设备不存在 //设备不存在
ErrorCode.DEVICE_NOT_EXIST.toString() -> { ErrorCode.DEVICE_NOT_EXIST.toString() -> {
if (isShowCodeError) showToast(R.string.txt_no_dfu) 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) { private fun onLayoutChange(translateView: View, translateY: Int) {
mTranslateView = translateView mTranslateView = translateView
//获取当前屏幕内容的高度 //获取当前屏幕内容的高度
val screenHeight = window.decorView.height val screenHeight = translateView.height
//获取View可见区域的bottom //获取View可见区域的bottom
val rect = Rect() val rect = Rect()
window.decorView.getWindowVisibleDisplayFrame(rect) translateView.getWindowVisibleDisplayFrame(rect)
if (screenHeight - getNavigatorBarHeight() > rect.bottom) { if (screenHeight - getNavigatorBarHeight() > rect.bottom) {
// 获取按钮的左上角按钮高度为40dp // 获取按钮的左上角按钮高度为40dp
// val location = IntArray(2) // 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) // val bottom = location[1] + resources.getDimensionPixelSize(R.dimen.dp_80)
//// 如果按钮被覆盖,移动整个界面向上移动 //// 如果按钮被覆盖,移动整个界面向上移动
// if (bottom > rect.bottom) { // if (bottom > rect.bottom) {
// window.decorView.scrollBy(0, bottom - rect.bottom) // translateView.scrollBy(0, bottom - rect.bottom)
// isKeyboardTranslate = true // isKeyboardTranslate = true
// } // }
if (!isKeyboardTranslate) { if (!isKeyboardTranslate) {
@@ -864,5 +882,28 @@ abstract class BaseActivity<T : ViewBinding>(val inflater: (inflater: LayoutInfl
hideSoftKeyboardCallback() 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************************************/ /*****************************监听软键盘弹出输入框上移end************************************/
} }

View File

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

View File

@@ -24,5 +24,9 @@ data class PackageBean(
var planTimeMonthsCount: Int, var planTimeMonthsCount: Int,
var everyMonthSafeFee: Double, var everyMonthSafeFee: Double,
var billedMode: String, var billedMode: String,
var selected: Boolean var selected: Boolean,
var bottomBgColor: String,
var listTitleCode: Int,
var planNameCode: Int,
var list: MutableList<PackageBenefitsBean>?
) : Parcelable ) : Parcelable

View File

@@ -1,8 +1,12 @@
package com.abbidot.tracker.bean package com.abbidot.tracker.bean
import android.os.Parcelable
import kotlinx.parcelize.Parcelize
/** /**
*Created by .yzq on 2024/9/5/005. *Created by .yzq on 2024/9/5/005.
* @link * @link
* @description: * @description:
*/ */
data class PackageBenefitsBean(var title: String, var status: Int, var titleCode: Int) @Parcelize
data class PackageBenefitsBean(var title: String, var status: Int, var titleCode: Int) : Parcelable

View File

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

View File

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

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.BikingRouteResult
import com.baidu.mapapi.search.route.DrivingRouteResult import com.baidu.mapapi.search.route.DrivingRouteResult
import com.baidu.mapapi.search.route.IndoorRouteResult 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.MassTransitRouteResult
import com.baidu.mapapi.search.route.OnGetRoutePlanResultListener import com.baidu.mapapi.search.route.OnGetRoutePlanResultListener
import com.baidu.mapapi.search.route.PlanNode import com.baidu.mapapi.search.route.PlanNode
@@ -144,6 +145,10 @@ class RoutePlanningViewModel : ViewModel() {
override fun onGetBikingRouteResult(p0: BikingRouteResult?) { override fun onGetBikingRouteResult(p0: BikingRouteResult?) {
} }
override fun onGetIntegralRouteResult(p0: IntegralRouteResult?) {
}
}) })
} }

View File

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

View File

@@ -2,8 +2,10 @@ package com.abbidot.tracker.dialog
import android.content.Context import android.content.Context
import android.widget.CompoundButton import android.widget.CompoundButton
import com.abbidot.baselibrary.constant.MMKVKey
import com.abbidot.baselibrary.list.BaseRecyclerAdapter import com.abbidot.baselibrary.list.BaseRecyclerAdapter
import com.abbidot.baselibrary.util.AppUtils import com.abbidot.baselibrary.util.AppUtils
import com.abbidot.baselibrary.util.MMKVUtil
import com.abbidot.tracker.base.BaseDialog import com.abbidot.tracker.base.BaseDialog
import com.abbidot.tracker.bean.DataBean import com.abbidot.tracker.bean.DataBean
import com.abbidot.tracker.databinding.DialogSelectMapTypeLayoutBinding import com.abbidot.tracker.databinding.DialogSelectMapTypeLayoutBinding
@@ -18,12 +20,14 @@ import com.abbidot.tracker.util.ViewUtil
class SelectMapTypeDialog( class SelectMapTypeDialog(
context: Context, context: Context,
adapter: BaseRecyclerAdapter<*>, adapter: BaseRecyclerAdapter<*>,
checkedChangeListener: CompoundButton.OnCheckedChangeListener? = null fenceCheckedChangeListener: CompoundButton.OnCheckedChangeListener? = null,
dashedCheckedChangeListener: CompoundButton.OnCheckedChangeListener? = null
) : BaseDialog<DialogSelectMapTypeLayoutBinding>( ) : BaseDialog<DialogSelectMapTypeLayoutBinding>(
DialogSelectMapTypeLayoutBinding::inflate, context DialogSelectMapTypeLayoutBinding::inflate, context
) { ) {
private var mAdapter = adapter private var mAdapter = adapter
private val mCheckedChangeListener = checkedChangeListener private val mFenceCheckedChangeListener = fenceCheckedChangeListener
private val mDashedCheckedChangeListener = dashedCheckedChangeListener
override fun initView() { override fun initView() {
mViewBinding.apply { mViewBinding.apply {
@@ -31,7 +35,10 @@ class SelectMapTypeDialog(
context, rvShowMapTypeList, mAdapter, right = AppUtils.dpToPx(58) context, rvShowMapTypeList, mAdapter, right = AppUtils.dpToPx(58)
) )
cbDialogMapFencesSwitch.isChecked = Util.getShowFenceSp() 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) { fun setFencesSwitch(checked: Boolean) {
mViewBinding.cbDialogMapFencesSwitch.isChecked = checked mViewBinding.cbDialogMapFencesSwitch.isChecked = checked
} }
fun setDashedSwitch(checked: Boolean) {
mViewBinding.cbDialogMapDashedLineSwitch.isChecked = checked
}
} }

View File

@@ -21,15 +21,17 @@ import java.util.Calendar
* @link * @link
* @description:显示日历弹窗 * @description:显示日历弹窗
* @param canSelectFutureDate 平时正常日期true不能选择未来时间 * @param canSelectFutureDate 平时正常日期true不能选择未来时间
* @param minLastDayRange 最小天数能选最近多少天0表示没有限制
*/ */
class ShowCalenderAndTimeDialog( class ShowCalenderAndTimeDialog(
context: Context, context: Context,
showCalenderTextView: TextView, showCalenderTextView: TextView,
okListener: OnDialogOkListener? = null, okListener: OnDialogSelectListener? = null,
format: String = Utils.DATE_FORMAT_PATTERN_EN1, format: String = Utils.DATE_FORMAT_PATTERN_EN1,
canSelectFutureDate: Boolean = false, canSelectFutureDate: Boolean = false,
calenderShowTimestamp: Long = 0, calenderShowTimestamp: Long = 0,
minYear: Int = 2023 minYear: Int = 2023,
minLastDayRange: Int = 0
) : BaseDialog<DialogCalenderAndTimeLayoutBinding>( ) : BaseDialog<DialogCalenderAndTimeLayoutBinding>(
DialogCalenderAndTimeLayoutBinding::inflate, context DialogCalenderAndTimeLayoutBinding::inflate, context
), OnValueChangeListener { ), OnValueChangeListener {
@@ -44,7 +46,8 @@ class ShowCalenderAndTimeDialog(
private val mOkListener = okListener private val mOkListener = okListener
private val mMinYear = minYear private val mMinYear = minYear
private val mCalenderShowTimestamp = calenderShowTimestamp private var mCalenderShowTimestamp = calenderShowTimestamp
private val mMinLastDayRange = minLastDayRange
override fun initView() { override fun initView() {
mMonths = context.resources.getStringArray(R.array.array_month) mMonths = context.resources.getStringArray(R.array.array_month)
@@ -58,8 +61,24 @@ class ShowCalenderAndTimeDialog(
val cYear = calendar.get(Calendar.YEAR) val cYear = calendar.get(Calendar.YEAR)
val month = calendar.get(Calendar.MONTH) + 1 val month = calendar.get(Calendar.MONTH) + 1
val day = calendar.get(Calendar.DAY_OF_MONTH) val day = calendar.get(Calendar.DAY_OF_MONTH)
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) it.setRange(mMinYear, 1, 1, cYear, month, day)
} }
}
updateMonthYear() updateMonthYear()
it.setOnMonthChangeListener { year, month -> it.setOnMonthChangeListener { year, month ->
@@ -86,7 +105,7 @@ class ShowCalenderAndTimeDialog(
0, 0,
23, 23,
5, 5,
24, 16,
NumberPickerValueFill0Format(), NumberPickerValueFill0Format(),
this@ShowCalenderAndTimeDialog this@ShowCalenderAndTimeDialog
) )
@@ -98,14 +117,12 @@ class ShowCalenderAndTimeDialog(
0, 0,
59, 59,
5, 5,
24, 16,
NumberPickerValueFill0Format(), NumberPickerValueFill0Format(),
this@ShowCalenderAndTimeDialog this@ShowCalenderAndTimeDialog
) )
} }
//根据传入的时间戳进行还原显示
setSelectDate(mCalenderShowTimestamp)
setOnClickListenerViews( setOnClickListenerViews(
llDialogCalenderLayout.ivSelectCalendarMonthLeft, llDialogCalenderLayout.ivSelectCalendarMonthLeft,
@@ -117,6 +134,12 @@ class ShowCalenderAndTimeDialog(
} }
} }
override fun onStart() {
super.onStart()
//根据传入的时间戳进行还原显示
setSelectDate(mCalenderShowTimestamp)
}
/** /**
* 根据传入的时间戳进行还原显示 * 根据传入的时间戳进行还原显示
* @param showTimestamp 13位时间戳 * @param showTimestamp 13位时间戳
@@ -172,16 +195,18 @@ class ShowCalenderAndTimeDialog(
}:${Utils.fill2Digits(npDialogCalenderMin.value)}:00" }:${Utils.fill2Digits(npDialogCalenderMin.value)}:00"
val timesTamp = Utils.stringToTimestamp(selectMonthYear) val timesTamp = Utils.stringToTimestamp(selectMonthYear)
val nowTimestamp = System.currentTimeMillis() val nowTimestamp = System.currentTimeMillis()
if (timesTamp > nowTimestamp) { if (timesTamp > nowTimestamp) {
//时间戳还原 mCalenderShowTimestamp = nowTimestamp
setSelectDate(nowTimestamp)
mShowCalenderTextView.text = Utils.formatTime(nowTimestamp, mDateFormat) mShowCalenderTextView.text = Utils.formatTime(nowTimestamp, mDateFormat)
mOkListener?.onSelectClick(this@ShowCalenderAndTimeDialog, nowTimestamp)
} else { } else {
mCalenderShowTimestamp = timesTamp
mShowCalenderTextView.text = Utils.stringToDate( mShowCalenderTextView.text = Utils.stringToDate(
selectMonthYear, Utils.DATE_FORMAT_PATTERN_CN2, mDateFormat selectMonthYear, Utils.DATE_FORMAT_PATTERN_CN2, mDateFormat
) )
mOkListener?.onSelectClick(this@ShowCalenderAndTimeDialog, timesTamp)
} }
mOkListener?.onOkClick(this@ShowCalenderAndTimeDialog)
dismiss() dismiss()
} }
} }

View File

@@ -100,7 +100,7 @@ class ShowCalenderDialog(
* 根据传入的时间戳进行还原显示 * 根据传入的时间戳进行还原显示
* @param showTimestamp 13位时间戳 * @param showTimestamp 13位时间戳
*/ */
fun setSelectDate(showTimestamp: Long) { private fun setSelectDate(showTimestamp: Long) {
if (showTimestamp > 0) { if (showTimestamp > 0) {
val calendar = java.util.Calendar.getInstance().apply { val calendar = java.util.Calendar.getInstance().apply {
timeInMillis = showTimestamp timeInMillis = showTimestamp

View File

@@ -837,6 +837,16 @@ interface INetworkService {
@Query("toTime") toTime: Long @Query("toTime") toTime: Long
): BaseResponse<MutableList<HistoryDataBean>> ): 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 @Query("userId") userId: String, @Query("deviceId") deviceId: String
): BaseResponse<MutableList<SubscriptionsOrderBean>> ): BaseResponse<MutableList<SubscriptionsOrderBean>>
/**
* 获取设备充值得的历史记录(包括自动续订)
*/
@GET("order$SUBSCRIPTIONS_V3/subscriptions/historyIncludRenew")
suspend fun getHistoryIncludeRenew(
@Query("subscriptionId") subscriptionId: String
): BaseResponse<MutableList<SubscriptionsOrderBean>>
/** /**
* 提交退款申请 * 提交退款申请
*/ */
@FormUrlEncoded @FormUrlEncoded
@POST("order$SUBSCRIPTIONS_V3/refund/commit") @POST("order$SUBSCRIPTIONS_V3/refund/commit")
suspend fun commitRefund( suspend fun commitRefund(
@Field("currency_code") currency_code: String, @Field("currency_code") currencyCode: String,
@Field("orderNum") orderNum: String, @Field("orderNum") orderNum: String,
@Field("chargeId") chargeId: String, @Field("chargeId") chargeId: String,
@Field("amount") amount: Int, @Field("amount") amount: Int,

View File

@@ -753,6 +753,13 @@ object NetworkApi : BaseNetworkApi<INetworkService>(INetworkService.BASE_URL) {
service.getHistoryByDay(deviceId, fromTime, toTime) 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) service.getSubscriptionsHistory(userId, deviceId)
} }
/**
* 获取设备充值得的历史记录(包括自动续订)
*/
suspend fun getHistoryIncludeRenew(subscriptionId: String) = getResult {
service.getHistoryIncludeRenew(subscriptionId)
}
/** /**
* 获取设备充值得的历史记录 * 获取设备充值得的历史记录
*/ */
suspend fun commitRefund( suspend fun commitRefund(
currency_code: String, currencyCode: String,
orderId: String, orderId: String,
chargeId: String, chargeId: String,
amount: Int, amount: Int,
@@ -1182,7 +1196,7 @@ object NetworkApi : BaseNetworkApi<INetworkService>(INetworkService.BASE_URL) {
payType: Int payType: Int
) = getResult { ) = getResult {
service.commitRefund( service.commitRefund(
currency_code, currencyCode,
orderId, orderId,
chargeId, chargeId,
amount, 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.activity.device.MyTrackerV2Activity
import com.abbidot.tracker.ui.fragment.account.AccountV2Fragment import com.abbidot.tracker.ui.fragment.account.AccountV2Fragment
import com.abbidot.tracker.ui.fragment.data.ActivityV2Fragment 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.map.MapV3Fragment
import com.abbidot.tracker.ui.fragment.pet.PetV2Fragment import com.abbidot.tracker.ui.fragment.pet.PetV2Fragment
import com.abbidot.tracker.util.SocketUtilManage import com.abbidot.tracker.util.SocketUtilManage
@@ -65,7 +65,6 @@ import com.hjq.permissions.XXPermissions
import com.hjq.permissions.permission.PermissionLists import com.hjq.permissions.permission.PermissionLists
import com.huantansheng.easyphotos.EasyPhotos import com.huantansheng.easyphotos.EasyPhotos
import com.qmuiteam.qmui.widget.QMUITopBar import com.qmuiteam.qmui.widget.QMUITopBar
import com.tencent.bugly.crashreport.CrashReport
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@@ -111,7 +110,7 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
private val mFragments = mutableListOf<Fragment>( private val mFragments = mutableListOf<Fragment>(
ActivityV2Fragment.newInstance(this), ActivityV2Fragment.newInstance(this),
RouteV2Fragment.newInstance(this), RouteV3Fragment.newInstance(this),
MapV3Fragment.newInstance(this), MapV3Fragment.newInstance(this),
PetV2Fragment.newInstance(this), PetV2Fragment.newInstance(this),
AccountV2Fragment.newInstance(this) AccountV2Fragment.newInstance(this)
@@ -212,10 +211,11 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
mDataViewModel.getHomeBindPetList(this@HomeV2Activity) mDataViewModel.getHomeBindPetList(this@HomeV2Activity)
//设置bugly的用户id //设置bugly的用户id
CrashReport.setUserId(MMKVUtil.getString(MMKVKey.Email)) // CrashReport.setUserId(MMKVUtil.getString(MMKVKey.Email))
//预先加载相册,防止上传头像几千张照片加载慢 //预先加载相册,防止上传头像几千张照片加载慢
XXPermissions.with(this).permission(PermissionLists.getReadMediaImagesPermission()) XXPermissions.with(this).permission(PermissionLists.getReadMediaImagesPermission())
.request { _, allGranted -> .request { _, deniedList ->
val allGranted = deniedList.isEmpty()
if (allGranted) { if (allGranted) {
EasyPhotos.preLoad(this) EasyPhotos.preLoad(this)
// { // {
@@ -310,7 +310,7 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
//蓝牙连接就去连接socket //蓝牙连接就去连接socket
// mBleReportManage.dealBleReportData(macID, null) // mBleReportManage.dealBleReportData(macID, null)
} else { } else {
mLogBleReportViewModel.uploadLog(mContext, macID) mLogBleReportViewModel.uploadLog(mContext, macID, deviceOutId)
startCountDownConBle(15) startCountDownConBle(15)
} }
} }
@@ -454,13 +454,13 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
packageUnavailableState() packageUnavailableState()
//刚开始打开APP上传日志 //刚开始打开APP上传日志
getPet(false)?.apply { getPet(false)?.apply {
mLogBleReportViewModel.uploadLog(mContext, macID) mLogBleReportViewModel.uploadLog(mContext, macID, deviceOutId)
} }
} else { } else {
onChangeClick(mSelectPetPosition) onChangeClick(mSelectPetPosition)
when (mViewBinding.homeV2ViewPager2.currentItem) { when (mViewBinding.homeV2ViewPager2.currentItem) {
0 -> { 0 -> {
(mFragments[1] as RouteV2Fragment).setNeedUpdateTag() (mFragments[1] as RouteV3Fragment).setNeedUpdateTag()
(mFragments[3] as PetV2Fragment).setNeedUpdateTag() (mFragments[3] as PetV2Fragment).setNeedUpdateTag()
} }
@@ -471,13 +471,13 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
2, 4 -> { 2, 4 -> {
(mFragments[0] as ActivityV2Fragment).setNeedUpdateTag() (mFragments[0] as ActivityV2Fragment).setNeedUpdateTag()
(mFragments[1] as RouteV2Fragment).setNeedUpdateTag() (mFragments[1] as RouteV3Fragment).setNeedUpdateTag()
(mFragments[3] as PetV2Fragment).setNeedUpdateTag() (mFragments[3] as PetV2Fragment).setNeedUpdateTag()
} }
3 -> { 3 -> {
(mFragments[0] as ActivityV2Fragment).setNeedUpdateTag() (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() { private fun checkPermissions() {
val checkBleOpen = MMKVUtil.getBoolean(MMKVKey.isFirstCheckBleOpen, true) val checkBleOpen = MMKVUtil.getBoolean(MMKVKey.isFirstCheckBleOpen, true)
if (checkBleOpen) MMKVUtil.putBoolean(MMKVKey.isFirstCheckBleOpen, false) if (checkBleOpen) MMKVUtil.putBoolean(MMKVKey.isFirstCheckBleOpen, false)
Util.checkBluetoothPermissionsEnabled(mContext, { Util.checkBluetoothPermissionsEnabled(this, {
// mAutomaticConnectionDeviceViewModel.autoConnectBleDevice(mContext) // mAutomaticConnectionDeviceViewModel.autoConnectBleDevice(mContext)
}, isCheckBleOpen = checkBleOpen) }, isCheckBleOpen = checkBleOpen)
} }
@@ -638,7 +638,7 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
fun refreshLocationBtnState() { fun refreshLocationBtnState() {
when (mViewBinding.homeV2ViewPager2.currentItem) { when (mViewBinding.homeV2ViewPager2.currentItem) {
0 -> (mFragments[0] as ActivityV2Fragment).checkNotifyLocationState() 0 -> (mFragments[0] as ActivityV2Fragment).checkNotifyLocationState()
1 -> (mFragments[1] as RouteV2Fragment).checkNotifyLocationState() 1 -> (mFragments[1] as RouteV3Fragment).checkNotifyLocationState()
3 -> (mFragments[3] as PetV2Fragment).checkNotifyLocationState() 3 -> (mFragments[3] as PetV2Fragment).checkNotifyLocationState()
} }
} }
@@ -654,7 +654,7 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
mChangePetListDialogAdapter.setSelectPetPos(mSelectPetPosition) mChangePetListDialogAdapter.setSelectPetPos(mSelectPetPosition)
when (mViewBinding.homeV2ViewPager2.currentItem) { when (mViewBinding.homeV2ViewPager2.currentItem) {
0 -> (mFragments[0] as ActivityV2Fragment).showPetNameAndHead(position) 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) 2 -> (mFragments[2] as MapV3Fragment).showPetNameAndHead(position)
3 -> (mFragments[3] as PetV2Fragment).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.hjq.toast.Toaster
import com.qmuiteam.qmui.arch.QMUIActivity import com.qmuiteam.qmui.arch.QMUIActivity
import com.stripe.android.PaymentConfiguration import com.stripe.android.PaymentConfiguration
import com.tencent.bugly.crashreport.CrashReport
import com.tencent.mm.opensdk.constants.ConstantsAPI import com.tencent.mm.opensdk.constants.ConstantsAPI
import com.tencent.mm.opensdk.openapi.IWXAPI import com.tencent.mm.opensdk.openapi.IWXAPI
import java.util.* import java.util.Calendar
/** /**
@@ -179,7 +178,7 @@ class SplashActivity : QMUIActivity() {
// }, 600) // }, 600)
// } // }
mViewBinding.splashLogoIv.visibility = View.VISIBLE mViewBinding.splashLogoIv.visibility = View.VISIBLE
mCountDownTimerViewModel.startCountDown(2) mCountDownTimerViewModel.startCountDown(1)
init() init()
} }
@@ -219,9 +218,9 @@ class SplashActivity : QMUIActivity() {
initMapbox() initMapbox()
} }
val buglyKey = Util.getMetadata(applicationContext, KeyNames.BUG_LY_KEY_NAME)
//腾讯bugly初始化 //腾讯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() { private fun initMapbox() {

View File

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

View File

@@ -10,6 +10,7 @@ import com.abbidot.tracker.base.BaseActivity
import com.abbidot.tracker.base.BaseDialog import com.abbidot.tracker.base.BaseDialog
import com.abbidot.tracker.constant.GetResultCallback import com.abbidot.tracker.constant.GetResultCallback
import com.abbidot.tracker.databinding.ActivityEmailAddressBinding import com.abbidot.tracker.databinding.ActivityEmailAddressBinding
import com.abbidot.tracker.util.Util
import com.abbidot.tracker.util.ViewUtil import com.abbidot.tracker.util.ViewUtil
import com.abbidot.tracker.vm.UserProfileViewModel import com.abbidot.tracker.vm.UserProfileViewModel
@@ -25,7 +26,7 @@ class EmailAddressActivity :
setTopBarTitle(R.string.txt_email_address) setTopBarTitle(R.string.txt_email_address)
mViewBinding.apply { mViewBinding.apply {
setOnClickListenerViews(btnEmailAddressChange) setOnClickListenerViews(btnEmailAddressChange, tvEmailAddressShow)
} }
} }
@@ -66,6 +67,9 @@ class EmailAddressActivity :
mViewBinding.apply { mViewBinding.apply {
when (v!!) { when (v!!) {
btnEmailAddressChange -> startChange() 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 -> mPullAction?.let { p ->
mViewBinding.ilNotificationV2MessageLayout.pullRefreshAndLoadMoreLayout.finishActionRun( mViewBinding.ilNotificationV2MessageLayout.pullRefreshAndLoadMoreLayout.finishActionRun(
p p

View File

@@ -98,11 +98,9 @@ class UserProfileActivity :
ilUserProfileEmailLayout.ivInputRepresentImage ilUserProfileEmailLayout.ivInputRepresentImage
) )
mUploadImageUrl = MMKVUtil.getString(MMKVKey.HeadUrl) // mUploadImageUrl = MMKVUtil.getString(MMKVKey.HeadUrl)
ViewUtil.instance.imageLoadUrl( ViewUtil.instance.imageLoadUrl(
ilUserProfileHeadLayout.ilPetProfileHead.appHeadImage, ilUserProfileHeadLayout.ilPetProfileHead.appHeadImage, "", R.drawable.pic_avatar_df
mUploadImageUrl,
R.drawable.pic_avatar_df
) )
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -135,8 +135,8 @@ class AddNewTracker3Activity :
} }
} }
override fun onErrorCode() { override fun onInterceptCode() {
super.onErrorCode() super.onInterceptCode()
mViewBinding.ivAddNewTracker3RefreshBtn.isEnabled = true mViewBinding.ivAddNewTracker3RefreshBtn.isEnabled = true
setNoConnectState() setNoConnectState()
} }

View File

@@ -0,0 +1,52 @@
package com.abbidot.tracker.ui.activity.device
import android.content.Intent
import com.abbidot.tracker.R
import com.abbidot.tracker.base.BaseActivity
import com.abbidot.tracker.bean.PetBean
import com.abbidot.tracker.constant.ConstantInt
import com.abbidot.tracker.constant.ConstantString
import com.abbidot.tracker.databinding.ActivityInitializingDeviceBinding
import com.abbidot.tracker.ui.activity.device.wifi.AddWifiPowerZone1Activity
import com.abbidot.tracker.util.Util
class InitializingDeviceActivity :
BaseActivity<ActivityInitializingDeviceBinding>(ActivityInitializingDeviceBinding::inflate) {
private var mPetBean: PetBean? = null
private var isFirstBind = false
private var mDeviceType = ConstantInt.Type1
override fun getTopBar() = null
override fun initData() {
super.initData()
intent.extras?.apply {
isFirstBind = getBoolean(ConstantString.isFirstBind, false)
mPetBean = Util.getParcelableAdaptive(intent, ConstantString.Pet, PetBean::class.java)
mDeviceType = getInt(ConstantString.Type, ConstantInt.Type1)
}
mViewBinding.apply {
val str = if (mDeviceType == ConstantInt.Type2) {
tvPaySuccessInitDeviceDec.setText(R.string.txt_init_g40_dec)
ivInitDeviceFlashImage.setImageResource(R.drawable.icon_init_g40_flash_image)
String.format(getString(R.string.txt_init_device_tip), "1-5")
} else String.format(getString(R.string.txt_init_device_tip), "15-20")
tvPaySuccessInitDeviceTip.text = str
btnPaySuccessInitDeviceNext.setOnClickListener {
val intent = Intent(mContext, AddWifiPowerZone1Activity::class.java)
intent.putExtra(ConstantString.Pet, mPetBean)
intent.putExtra(ConstantString.isFirstBind, isFirstBind)
startActivityFinish(intent)
}
}
}
override fun leftBackOnClick() {
}
}

View File

@@ -71,6 +71,9 @@ open class AddAndEditFencesZoneBaseActivity :
var mFencesList: GetFencesBean? = null var mFencesList: GetFencesBean? = null
var isEditFences = false var isEditFences = false
//冻结点击
private var isBlockedClick = false
private var mShowCenterLocationType = ConstantInt.OtherLocationType private var mShowCenterLocationType = ConstantInt.OtherLocationType
private val mDefaultFencesName = private val mDefaultFencesName =
arrayOf("Home", "Office", "Garden", "Park", "Play", "Unsafe", "Vegetable Garden", "Water") arrayOf("Home", "Office", "Garden", "Park", "Play", "Unsafe", "Vegetable Garden", "Water")
@@ -181,6 +184,7 @@ open class AddAndEditFencesZoneBaseActivity :
rlAddEditFencesZoneInfoLayout.setOnTouchListener { v, event -> rlAddEditFencesZoneInfoLayout.setOnTouchListener { v, event ->
when (event.action) { when (event.action) {
MotionEvent.ACTION_DOWN -> { MotionEvent.ACTION_DOWN -> {
hideInputMethod(v)
oldY = event.y oldY = event.y
} }
@@ -188,6 +192,7 @@ open class AddAndEditFencesZoneBaseActivity :
} }
MotionEvent.ACTION_UP -> { MotionEvent.ACTION_UP -> {
if (!isKeyboardTranslate) {
if (event.y - oldY > slideDis) { if (event.y - oldY > slideDis) {
downLayout() downLayout()
} else if (event.y - oldY < -slideDis) { } else if (event.y - oldY < -slideDis) {
@@ -195,6 +200,7 @@ open class AddAndEditFencesZoneBaseActivity :
} }
} }
} }
}
false false
} }
//监听布局变化 //监听布局变化
@@ -203,11 +209,16 @@ open class AddAndEditFencesZoneBaseActivity :
} }
} }
setListenKeyboardChange() setListenKeyboardChange(methodType = ConstantInt.Type1)
setFenceName() setFenceName()
} }
override fun leftBackOnClick() {
if (isBlockedClick) return
super.leftBackOnClick()
}
open fun mapLoadOk() { open fun mapLoadOk() {
drawFences() drawFences()
} }
@@ -355,7 +366,7 @@ open class AddAndEditFencesZoneBaseActivity :
override fun onRequestError(exceptionCode: String?) { override fun onRequestError(exceptionCode: String?) {
super.onRequestError(exceptionCode) 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 R.string.txt_delete_success, isFinish = true, gravity = Gravity.CENTER
) )
} }
override fun onRequestError(exceptionCode: String?) {
super.onRequestError(exceptionCode)
setDisableState(false)
}
}) })
} }
mFencesManageViewModel.mUpdateFenceLiveData.observe(this) { mFencesManageViewModel.mUpdateFenceLiveData.observe(this) {
@@ -388,7 +404,7 @@ open class AddAndEditFencesZoneBaseActivity :
override fun onRequestError(exceptionCode: String?) { override fun onRequestError(exceptionCode: String?) {
super.onRequestError(exceptionCode) super.onRequestError(exceptionCode)
setButtonEnabled(mViewBinding.btnSaveFencesZone, ConstantInt.Type1) setDisableState(false)
} }
}) })
} }
@@ -413,6 +429,23 @@ open class AddAndEditFencesZoneBaseActivity :
showToast(resStringId, isFinish = true, gravity = Gravity.CENTER) 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) { override fun onWindowFocusChanged(hasFocus: Boolean) {
super.onWindowFocusChanged(hasFocus) super.onWindowFocusChanged(hasFocus)
bottomMarginOverlap() bottomMarginOverlap()
@@ -656,7 +689,7 @@ open class AddAndEditFencesZoneBaseActivity :
else ConstantInt.Type2 else ConstantInt.Type2
} }
mActionType = ConstantInt.Type0 mActionType = ConstantInt.Type0
setButtonEnabled(mViewBinding.btnSaveFencesZone, ConstantInt.Type0) setDisableState(true)
name = fenceName name = fenceName
when (fenceShapeType) { when (fenceShapeType) {
ConstantInt.CircleShapeType -> { ConstantInt.CircleShapeType -> {
@@ -684,13 +717,14 @@ open class AddAndEditFencesZoneBaseActivity :
* 更新围栏 * 更新围栏
*/ */
fun updateFences(fencesBean: FencesBean) { fun updateFences(fencesBean: FencesBean) {
if (isBlockedClick) return
val fenceName = mViewBinding.ilFencesZoneNameInput.etInputContent.text.toString() val fenceName = mViewBinding.ilFencesZoneNameInput.etInputContent.text.toString()
if (TextUtils.isEmpty(fenceName)) { if (TextUtils.isEmpty(fenceName)) {
showToast(R.string.txt_not_null, gravity = Gravity.CENTER) showToast(R.string.txt_not_null, gravity = Gravity.CENTER)
return return
} }
mActionType = ConstantInt.Type1 mActionType = ConstantInt.Type1
setButtonEnabled(mViewBinding.btnSaveFencesZone, ConstantInt.Type0) setDisableState(true)
mPetBean?.let { mPetBean?.let {
if (BleManager.getInstance().isConnected(it.macID)) { if (BleManager.getInstance().isConnected(it.macID)) {
sendFenceData() sendFenceData()
@@ -743,12 +777,14 @@ open class AddAndEditFencesZoneBaseActivity :
* 删除围栏 * 删除围栏
*/ */
fun deleteFences(fencesBean: FencesBean) { fun deleteFences(fencesBean: FencesBean) {
if (isBlockedClick) return
ViewUtil.instance.showDialog( ViewUtil.instance.showDialog(
this, R.string.txt_delete_tips, object : BaseDialog.OnDialogOkListener { this, R.string.txt_delete_tips, object : BaseDialog.OnDialogOkListener {
override fun onOkClick(dialog: BaseDialog<*>) { override fun onOkClick(dialog: BaseDialog<*>) {
dialog.dismiss() dialog.dismiss()
mPetBean?.let { mPetBean?.let {
mActionType = ConstantInt.Type2 mActionType = ConstantInt.Type2
setDisableState(true)
if (BleManager.getInstance().isConnected(it.macID)) { if (BleManager.getInstance().isConnected(it.macID)) {
//删除蓝牙标志 //删除蓝牙标志
fencesBean.isOn = ConstantInt.Type2 fencesBean.isOn = ConstantInt.Type2
@@ -881,7 +917,7 @@ open class AddAndEditFencesZoneBaseActivity :
} }
tvFencesZoneShapeResetBtn -> recoverDefaultFencesView() tvFencesZoneShapeResetBtn -> recoverDefaultFencesView()
btnCancelFencesZone -> finish() btnCancelFencesZone -> if (!isBlockedClick) finish()
ivFencesZoneMapSwitchBtn -> switchMapType() ivFencesZoneMapSwitchBtn -> switchMapType()
} }
} }

View File

@@ -57,6 +57,9 @@ class PreviewFencesZoneActivity :
//操作类型0增加1编辑2删除 //操作类型0增加1编辑2删除
private var mActionType = ConstantInt.Type1 private var mActionType = ConstantInt.Type1
//冻结点击
private var isBlockedClick = false
override fun getTopBar() = mViewBinding.previewFencesZoneTopBar.titleTopBar override fun getTopBar() = mViewBinding.previewFencesZoneTopBar.titleTopBar
override fun initData() { override fun initData() {
@@ -129,6 +132,11 @@ class PreviewFencesZoneActivity :
} }
} }
override fun leftBackOnClick() {
if (isBlockedClick) return
super.leftBackOnClick()
}
override fun liveDataObserve() { override fun liveDataObserve() {
//获取所有围栏返回 //获取所有围栏返回
mFencesManageViewModel.mFencesLiveData.observe(this) { mFencesManageViewModel.mFencesLiveData.observe(this) {
@@ -167,6 +175,11 @@ class PreviewFencesZoneActivity :
XEventBus.post(EventName.DeleteFences) XEventBus.post(EventName.DeleteFences)
showToast(R.string.txt_delete_success, true, gravity = Gravity.CENTER) 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() { private fun deleteFences() {
if (isBlockedClick) return
ViewUtil.instance.showDialog( ViewUtil.instance.showDialog(
this, R.string.txt_delete_tips, object : BaseDialog.OnDialogOkListener { this, R.string.txt_delete_tips, object : BaseDialog.OnDialogOkListener {
override fun onOkClick(dialog: BaseDialog<*>) { override fun onOkClick(dialog: BaseDialog<*>) {
@@ -374,6 +388,7 @@ class PreviewFencesZoneActivity :
mPetBean?.let { mPetBean?.let {
mCurrentFences?.apply { mCurrentFences?.apply {
mActionType = ConstantInt.Type2 mActionType = ConstantInt.Type2
isBlockedClick = true
if (modeType == ConstantInt.Type3) modeType = ConstantInt.Type3 if (modeType == ConstantInt.Type3) modeType = ConstantInt.Type3
else if (BleManager.getInstance().isConnected(it.macID)) { else if (BleManager.getInstance().isConnected(it.macID)) {
//删除蓝牙标志 //删除蓝牙标志
@@ -402,7 +417,8 @@ class PreviewFencesZoneActivity :
} }
private fun goEditFences() { private fun goEditFences() {
Util.checkLocationPermissionsGpsEnabled(mContext, { if (isBlockedClick) return
Util.checkLocationPermissionsGpsEnabled(this, {
mCurrentFences?.apply { mCurrentFences?.apply {
val intent = if (fenceType == ConstantInt.SafeZone) Intent( val intent = if (fenceType == ConstantInt.SafeZone) Intent(
mContext, EditSafeZoneActivity::class.java mContext, EditSafeZoneActivity::class.java
@@ -422,7 +438,10 @@ class PreviewFencesZoneActivity :
btnPreviewFencesEdit -> goEditFences() btnPreviewFencesEdit -> goEditFences()
mRightImageButton -> deleteFences() mRightImageButton -> deleteFences()
cbPreviewFencesSwitch -> mCurrentFences?.apply { changeOnAndOff(this) } cbPreviewFencesSwitch -> {
if (isBlockedClick) return
mCurrentFences?.apply { changeOnAndOff(this) }
}
ivPreviewFencesMapSwitchBtn -> { ivPreviewFencesMapSwitchBtn -> {
mPreviewFencesMapCommon.switchSatelliteAndNormalMapType() mPreviewFencesMapCommon.switchSatelliteAndNormalMapType()

View File

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

View File

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

View File

@@ -245,7 +245,7 @@ class LedLightActivityV0 : BaseActivity<ActivityLedLightBinding>(ActivityLedLigh
setDisabledState(false) setDisabledState(false)
} else { } 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) { if (powerSwitch == ConstantInt.Type0 || powerSwitch == ConstantInt.Type2 || powerSwitch == ConstantInt.Type3 || inWifiZone == ConstantInt.Type1 || isTimeoutReport) {
setDisabledState(true) setDisabledState(true)
} else { } else {
@@ -294,7 +294,7 @@ class LedLightActivityV0 : BaseActivity<ActivityLedLightBinding>(ActivityLedLigh
private fun setBleLedMode(mode: Int) { private fun setBleLedMode(mode: Int) {
mBleTrackDeviceBean?.apply { 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() { private fun goEditWifiActivity() {
Util.checkLocationPermissionsGpsEnabled(mContext, { Util.checkLocationPermissionsGpsEnabled(this, {
val intent = Intent(mContext, EditWifiPowerZoneActivity::class.java) val intent = Intent(mContext, EditWifiPowerZoneActivity::class.java)
intent.putExtra(ConstantString.WiFi, mWiFiBean) intent.putExtra(ConstantString.WiFi, mWiFiBean)
mDecWiFiAddressData?.let { mDecWiFiAddressData?.let {

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