From c6f9e191b91811a218d7879ddb0a013de3cf90aa Mon Sep 17 00:00:00 2001 From: yezhiqiu <123456@qq.com> Date: Thu, 27 Aug 2026 17:32:35 +0800 Subject: [PATCH] =?UTF-8?q?1.=E5=9B=B4=E6=A0=8F=E5=92=8Cwifi=E9=80=82?= =?UTF-8?q?=E9=85=8D=E7=99=BE=E5=BA=A6=E5=9C=B0=E5=9B=BE=202.=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E9=A6=96=E6=AC=A1=E7=BB=91=E5=AE=9A=E6=B5=81=E7=A8=8B?= =?UTF-8?q?=E4=B8=AD=E6=B7=BB=E5=8A=A0wifi=20=EF=BC=8C=E5=AE=9A=E4=BD=8D?= =?UTF-8?q?=E7=82=B9=E6=9C=AA=E6=8C=89=E5=9B=BD=E5=86=85=E7=89=88=E7=BA=A0?= =?UTF-8?q?=E6=AD=A3bug=203.=E4=BC=98=E5=8C=96=E7=99=BE=E5=BA=A6=E5=92=8C?= =?UTF-8?q?=E8=B0=B7=E6=AD=8C=E5=AE=9A=E4=BD=8D=E5=85=A8=E5=B1=80=E5=8F=AA?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E4=B8=80=E4=B8=AA=204.=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=9C=AA=E4=BD=BF=E7=94=A8=E5=AD=97=E7=AC=A6=E4=B8=B2=EF=BC=8C?= =?UTF-8?q?=E6=95=B4=E7=90=86=E5=A4=9A=E8=AF=AD=E8=A8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 6 +- app/src/main/AndroidManifest.xml | 12 +- .../java/com/abbidot/tracker/MyApplication.kt | 20 +- .../com/abbidot/tracker/base/BaseActivity.kt | 28 +- .../com/abbidot/tracker/base/BaseMapCommon.kt | 68 +- .../map/baidumap/FencesAddBaiduMapFragment.kt | 47 +- .../baidumap/NavigationBaiduMapFragment.kt | 2 - .../googlemap/FencesAddGoogleMapFragment.kt | 2 - .../googlemap/NavigationGoogleMapFragment.kt | 1 - .../tracker/service/BaiduLocationService.kt | 84 +++ .../tracker/service/GoogleLocationService.kt | 116 +++ .../tracker/ui/activity/HomeV2Activity.kt | 31 +- .../device/AddPairedSuccessActivity.kt | 2 +- .../AddAndEditFencesZoneBaseActivity.kt | 52 +- .../device/wifi/AddWifiPowerZone2Activity.kt | 13 +- .../subscribe/PaymentSuccessActivity.kt | 2 +- .../subscribe/SureSubscriptionPlanActivity.kt | 46 +- .../ui/common/map/EditWifiZoneMapCommon.kt | 15 +- .../ui/common/map/FencesAddEditMapCommon.kt | 2 +- .../ui/common/map/HistoryDataMapCommon.kt | 15 +- .../ui/common/map/WifiZone2MapCommon.kt | 15 +- .../map/baidumap/BaseBaiduMapFragment.kt | 239 +++--- .../map/baidumap/EditWiFiZoneBaiduFragment.kt | 32 + .../baidumap/FencesAddEditBaiduMapFragment.kt | 325 ++++++-- .../baidumap/HistoryDataBaiduMapFragment.kt | 11 +- .../map/baidumap/HomeMapBaiduMapFragment.kt | 1 - .../baidumap/PreviewFencesBaiduMapFragment.kt | 1 - .../map/baidumap/WiFiZoneBaiduMapFragment.kt | 182 +++++ .../map/googlemap/BaseGoogleMapFragment.kt | 323 ++------ .../EditWiFiZoneGoogleMapFragment.kt | 58 +- .../FencesAddEditGoogleMapFragment.kt | 28 +- .../googlemap/HistoryDataGoogleMapFragment.kt | 2 - .../googlemap/HomeMapGoogleMapFragmentV3.kt | 1 - .../map/googlemap/MarkerInfoWindowAdapter.kt | 13 +- .../PreviewFencesGoogleMapFragment.kt | 1 - .../googlemap/WiFiZone2GoogleMapFragment.kt | 13 +- .../tracker/util/BaiduLocationManager.kt | 64 ++ .../abbidot/tracker/util/BleReportManage.kt | 8 +- .../tracker/util/GoogleLocationManager.kt | 64 ++ .../tracker/util/GoogleLocationUtil.java | 68 -- .../com/abbidot/tracker/util/ImageUtil.kt | 4 +- .../com/abbidot/tracker/util/LonAndLatUtil.kt | 4 - .../java/com/abbidot/tracker/util/Util.kt | 10 + .../abbidot/tracker/vm/DeviceDFUViewModel.kt | 2 + .../abbidot/tracker/vm/FencesMapViewModel.kt | 19 +- .../tracker/vm/GoogleLocationViewModel.kt | 3 - .../layout/activity_help_tracker_status.xml | 54 +- app/src/main/res/values-de/strings.xml | 703 ++++++++---------- app/src/main/res/values-fr/strings.xml | 679 ++++++++--------- app/src/main/res/values-zh-rCN/strings.xml | 559 +++++++------- app/src/main/res/values/strings.xml | 683 ++++++++--------- .../abbidot/baselibrary/constant/EventName.kt | 4 +- .../com/abbidot/baselibrary/util/AppUtils.kt | 2 +- 53 files changed, 2523 insertions(+), 2216 deletions(-) create mode 100644 app/src/main/java/com/abbidot/tracker/service/BaiduLocationService.kt create mode 100644 app/src/main/java/com/abbidot/tracker/service/GoogleLocationService.kt create mode 100644 app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/EditWiFiZoneBaiduFragment.kt create mode 100644 app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/WiFiZoneBaiduMapFragment.kt create mode 100644 app/src/main/java/com/abbidot/tracker/util/BaiduLocationManager.kt create mode 100644 app/src/main/java/com/abbidot/tracker/util/GoogleLocationManager.kt delete mode 100644 app/src/main/java/com/abbidot/tracker/util/GoogleLocationUtil.java diff --git a/app/build.gradle b/app/build.gradle index 5371b26..cc41de8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -28,9 +28,9 @@ android { applicationId "com.abbidot.tracker" minSdkVersion 24 targetSdkVersion 35 - versionCode 2400 - versionName "2.4.0" -// versionName "2.4.0-Beta1" + versionCode 2500 +// versionName "2.5.0" + versionName "2.5.0-Beta1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index bb2f322..147de58 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -87,7 +87,9 @@ android:usesPermissionFlags="neverForLocation" tools:targetApi="s" /> - + + + @@ -532,6 +534,14 @@ + + () } @@ -46,6 +48,8 @@ class MyApplication : Application() { Toaster.init(this) Toaster.setView(R.layout.toast_my_layout) + initLocationServer() + // JPushInterface.setDebugMode(true) // JPushInterface.init(this) @@ -79,9 +83,19 @@ class MyApplication : Application() { }.build() //设置全局唯一实例 Coil.setImageLoader(imageLoader) - } - CrashHandler().init(this) + CrashHandler().init(this) + } + } + + private fun initLocationServer() { + LogUtil.e("初始化定位服务") + //初始化定位服务,需要BaseActivity中startLocation()方法调用启动定位服务 + if (AppUtils.isChina()) { + BaiduLocationManager.init(this) + } else { + GoogleLocationManager.init(this) + } } /** diff --git a/app/src/main/java/com/abbidot/tracker/base/BaseActivity.kt b/app/src/main/java/com/abbidot/tracker/base/BaseActivity.kt index dbbcc86..6d5639b 100644 --- a/app/src/main/java/com/abbidot/tracker/base/BaseActivity.kt +++ b/app/src/main/java/com/abbidot/tracker/base/BaseActivity.kt @@ -1,6 +1,5 @@ package com.abbidot.tracker.base -import android.annotation.SuppressLint import android.app.Activity import android.content.Context import android.content.Intent @@ -36,6 +35,8 @@ import com.abbidot.baselibrary.util.MMKVUtil import com.abbidot.tracker.R import com.abbidot.tracker.constant.ConstantInt import com.abbidot.tracker.constant.GetResultCallback +import com.abbidot.tracker.util.BaiduLocationManager +import com.abbidot.tracker.util.GoogleLocationManager import com.abbidot.tracker.util.Util import com.abbidot.tracker.util.ViewUtil import com.baidu.platform.comapi.util.NetworkUtil @@ -590,7 +591,7 @@ abstract class BaseActivity(val inflater: (inflater: LayoutInfl //服务器返回错误信息 val exceptionMessage = it.exceptionOrNull()?.message //服务器返回错误code - val exceptionCode= it.exceptionOrNull()?.toString() + val exceptionCode = it.exceptionOrNull()?.toString() LogUtil.d("Throwable异常", "code=${exceptionCode},${exceptionMessage}") if (null != exceptionCode) { //处理验证码登录,用户未注册的情况 @@ -932,5 +933,28 @@ abstract class BaseActivity(val inflater: (inflater: LayoutInfl hideSoftKeyboardCallback() } } + /*****************************监听软键盘弹出,输入框上移end************************************/ + + /** + * 释放定位服务 + */ + private fun releaseLocationService() { + LogUtil.e("释放定位服务") + if (AppUtils.isChina()) { + BaiduLocationManager.releaseServer(this) + } else { + GoogleLocationManager.releaseServer(this) + } + } + + override fun onDestroy() { + super.onDestroy() + //判断是否为“完全退出”场景(例如:用户点击返回键退出应用) + //isFinishing:判断 Activity 是否正在被销毁。 + //isTaskRoot:判断当前 Activity 是否为任务栈的根 Activity(避免其他 Activity 销毁时误触发) + if (isFinishing && isTaskRoot) { + releaseLocationService() + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/abbidot/tracker/base/BaseMapCommon.kt b/app/src/main/java/com/abbidot/tracker/base/BaseMapCommon.kt index 79aaa72..87a0498 100644 --- a/app/src/main/java/com/abbidot/tracker/base/BaseMapCommon.kt +++ b/app/src/main/java/com/abbidot/tracker/base/BaseMapCommon.kt @@ -8,7 +8,6 @@ import com.abbidot.tracker.constant.ConstantInt import com.abbidot.tracker.ui.fragment.map.baidumap.BaseBaiduMapFragment import com.abbidot.tracker.ui.fragment.map.googlemap.BaseGoogleMapFragment import com.abbidot.tracker.util.Util -import com.baidu.mapapi.utils.DistanceUtil import com.google.android.gms.maps.model.LatLng /** @@ -39,7 +38,7 @@ open class BaseMapCommon { fun startRefreshUserLocation( baiduMapFragment: BaseBaiduMapFragment?, googleMapFragment: BaseGoogleMapFragment? ) { - googleMapFragment?.getLastLocation() +// googleMapFragment?.getLastLocation() //百度地图定位成功后,每隔60秒刷新用户位置,无需重复调用 } @@ -134,11 +133,20 @@ open class BaseMapCommon { context, padding, LatLng(ancillaryLatitude, ancillaryLongitude), + LatLng(latitudeCenter, longitudeCenter), LatLng(ancillaryOtherLatitude, ancillaryOtherLongitude) ) } baiduMapFragment?.apply { - setBaiduMapZoom(getDistanceZoom(radius.toDouble()) + 1) +// setBaiduMapZoom(getDistanceZoom(radius.toDouble()) + 1) + setLatLngZoom( + context, + com.baidu.mapapi.model.LatLng(ancillaryLatitude, ancillaryLongitude), + com.baidu.mapapi.model.LatLng(latitudeCenter, longitudeCenter), + com.baidu.mapapi.model.LatLng( + ancillaryOtherLatitude, ancillaryOtherLongitude + ) + ) } } @@ -152,13 +160,20 @@ open class BaseMapCommon { LatLng(latitudeD, longitudeD) ) baiduMapFragment?.apply { - setBaiduMapZoom( - getDistanceZoom( - maxOf( - shortDistance, longDistance - ).toDouble() - ) + 1 + setLatLngZoom( + context, + com.baidu.mapapi.model.LatLng(latitudeA, longitudeA), + com.baidu.mapapi.model.LatLng(latitudeB, longitudeB), + com.baidu.mapapi.model.LatLng(latitudeC, longitudeC), + com.baidu.mapapi.model.LatLng(latitudeD, longitudeD) ) +// setBaiduMapZoom( +// getDistanceZoom( +// maxOf( +// shortDistance, longDistance +// ).toDouble() +// ) + 1 +// ) } } @@ -174,20 +189,29 @@ open class BaseMapCommon { LatLng(latitudeF, longitudeF), ) baiduMapFragment?.apply { - val minLat = - minOf(latitudeA, latitudeB, latitudeC, latitudeD, latitudeE, latitudeF) - val maxLat = - minOf(latitudeA, latitudeB, latitudeC, latitudeD, latitudeE, latitudeF) - val minLon = minOf( - longitudeA, longitudeB, longitudeC, longitudeD, longitudeE, longitudeF + setLatLngZoom( + context, + com.baidu.mapapi.model.LatLng(latitudeA, longitudeA), + com.baidu.mapapi.model.LatLng(latitudeB, longitudeB), + com.baidu.mapapi.model.LatLng(latitudeC, longitudeC), + com.baidu.mapapi.model.LatLng(latitudeD, longitudeD), + com.baidu.mapapi.model.LatLng(latitudeE, longitudeE), + com.baidu.mapapi.model.LatLng(latitudeF, longitudeF), ) - val maxLon = minOf( - longitudeA, longitudeB, longitudeC, longitudeD, longitudeE, longitudeF - ) - val distance = DistanceUtil.getDistance( - getBaiduMapLatLng(minLat, minLon), getBaiduMapLatLng(maxLat, maxLon) - ) - setBaiduMapZoom(getDistanceZoom(distance)) +// val minLat = +// minOf(latitudeA, latitudeB, latitudeC, latitudeD, latitudeE, latitudeF) +// val maxLat = +// minOf(latitudeA, latitudeB, latitudeC, latitudeD, latitudeE, latitudeF) +// val minLon = minOf( +// longitudeA, longitudeB, longitudeC, longitudeD, longitudeE, longitudeF +// ) +// val maxLon = minOf( +// longitudeA, longitudeB, longitudeC, longitudeD, longitudeE, longitudeF +// ) +// val distance = DistanceUtil.getDistance( +// getBaiduMapLatLng(minLat, minLon), getBaiduMapLatLng(maxLat, maxLon) +// ) +// setBaiduMapZoom(getDistanceZoom(distance)) } } } diff --git a/app/src/main/java/com/abbidot/tracker/deprecated/ui/fragment/map/baidumap/FencesAddBaiduMapFragment.kt b/app/src/main/java/com/abbidot/tracker/deprecated/ui/fragment/map/baidumap/FencesAddBaiduMapFragment.kt index f6675c0..7a8e90f 100644 --- a/app/src/main/java/com/abbidot/tracker/deprecated/ui/fragment/map/baidumap/FencesAddBaiduMapFragment.kt +++ b/app/src/main/java/com/abbidot/tracker/deprecated/ui/fragment/map/baidumap/FencesAddBaiduMapFragment.kt @@ -16,8 +16,6 @@ import com.abbidot.tracker.constant.ConstantInt import com.abbidot.tracker.deprecated.ui.activity.profile.FencesAddActivity import com.abbidot.tracker.ui.common.map.FencesMapCommon import com.abbidot.tracker.ui.fragment.map.baidumap.BaseBaiduMapFragment -import com.abbidot.tracker.util.LonAndLatUtil.Companion.getMaxLatOrLon -import com.abbidot.tracker.util.LonAndLatUtil.Companion.getMinLatOrLon import com.abbidot.tracker.util.Util import com.abbidot.tracker.util.ViewUtil import com.abbidot.tracker.widget.FencesPolygonView @@ -88,8 +86,6 @@ class FencesAddBaiduMapFragment : BaseBaiduMapFragment() { if (fencesAddActivity.isEdit) { locationSuccess(null) - } else { - startLocation() } //测试矩形围栏使用的代码 @@ -276,27 +272,28 @@ class FencesAddBaiduMapFragment : BaseBaiduMapFragment() { fun setRectMapZoom( rectALatLng: LatLng, rectBLatLng: LatLng, rectCLatLng: LatLng, rectDLatLng: LatLng ) { - val maxLat = getMaxLatOrLon( - rectALatLng.latitude, rectBLatLng.latitude, rectCLatLng.latitude, rectDLatLng.latitude - ) - val maxLon = getMaxLatOrLon( - rectALatLng.longitude, - rectBLatLng.longitude, - rectCLatLng.longitude, - rectDLatLng.longitude - ) - val minLat = getMinLatOrLon( - rectALatLng.latitude, rectBLatLng.latitude, rectCLatLng.latitude, rectDLatLng.latitude - ) - val minLon = getMinLatOrLon( - rectALatLng.longitude, - rectBLatLng.longitude, - rectCLatLng.longitude, - rectDLatLng.longitude - ) - val zoom = getDistanceZoom(LatLng(minLat, minLon), LatLng(maxLat, maxLon)) - LogUtil.e("百度地图zoom==$zoom") - setBaiduMapZoom(zoom) +// val maxLat = getMaxLatOrLon( +// rectALatLng.latitude, rectBLatLng.latitude, rectCLatLng.latitude, rectDLatLng.latitude +// ) +// val maxLon = getMaxLatOrLon( +// rectALatLng.longitude, +// rectBLatLng.longitude, +// rectCLatLng.longitude, +// rectDLatLng.longitude +// ) +// val minLat = getMinLatOrLon( +// rectALatLng.latitude, rectBLatLng.latitude, rectCLatLng.latitude, rectDLatLng.latitude +// ) +// val minLon = getMinLatOrLon( +// rectALatLng.longitude, +// rectBLatLng.longitude, +// rectCLatLng.longitude, +// rectDLatLng.longitude +// ) +// val zoom = getDistanceZoom(LatLng(minLat, minLon), LatLng(maxLat, maxLon)) +// LogUtil.e("百度地图zoom==$zoom") +// setBaiduMapZoom(zoom) + setLatLngZoom(mContext!!, rectALatLng, rectBLatLng, rectCLatLng, rectDLatLng) } /** diff --git a/app/src/main/java/com/abbidot/tracker/deprecated/ui/fragment/map/baidumap/NavigationBaiduMapFragment.kt b/app/src/main/java/com/abbidot/tracker/deprecated/ui/fragment/map/baidumap/NavigationBaiduMapFragment.kt index bc215a8..feca80e 100644 --- a/app/src/main/java/com/abbidot/tracker/deprecated/ui/fragment/map/baidumap/NavigationBaiduMapFragment.kt +++ b/app/src/main/java/com/abbidot/tracker/deprecated/ui/fragment/map/baidumap/NavigationBaiduMapFragment.kt @@ -77,8 +77,6 @@ class NavigationBaiduMapFragment: BaseBaiduMapFragment() { isAnimMoveCamera = false, headBgResId = R.drawable.pic_map_location ) - - startLocation() } } diff --git a/app/src/main/java/com/abbidot/tracker/deprecated/ui/fragment/map/googlemap/FencesAddGoogleMapFragment.kt b/app/src/main/java/com/abbidot/tracker/deprecated/ui/fragment/map/googlemap/FencesAddGoogleMapFragment.kt index 3afe131..3957d87 100644 --- a/app/src/main/java/com/abbidot/tracker/deprecated/ui/fragment/map/googlemap/FencesAddGoogleMapFragment.kt +++ b/app/src/main/java/com/abbidot/tracker/deprecated/ui/fragment/map/googlemap/FencesAddGoogleMapFragment.kt @@ -72,8 +72,6 @@ class FencesAddGoogleMapFragment : BaseGoogleMapFragment() { if (fencesAddActivity.isEdit) { locationSuccess(null) - } else { - getLastLocation() } } diff --git a/app/src/main/java/com/abbidot/tracker/deprecated/ui/fragment/map/googlemap/NavigationGoogleMapFragment.kt b/app/src/main/java/com/abbidot/tracker/deprecated/ui/fragment/map/googlemap/NavigationGoogleMapFragment.kt index 70bef06..97858b4 100644 --- a/app/src/main/java/com/abbidot/tracker/deprecated/ui/fragment/map/googlemap/NavigationGoogleMapFragment.kt +++ b/app/src/main/java/com/abbidot/tracker/deprecated/ui/fragment/map/googlemap/NavigationGoogleMapFragment.kt @@ -137,7 +137,6 @@ class NavigationGoogleMapFragment: BaseGoogleMapFragment() { refreshPetCurrentLocation(mPetLatLng!!, isAnimMoveCamera = false, headBgResId = R.drawable.pic_map_location) - getLastLocation() } } diff --git a/app/src/main/java/com/abbidot/tracker/service/BaiduLocationService.kt b/app/src/main/java/com/abbidot/tracker/service/BaiduLocationService.kt new file mode 100644 index 0000000..4f4101a --- /dev/null +++ b/app/src/main/java/com/abbidot/tracker/service/BaiduLocationService.kt @@ -0,0 +1,84 @@ +package com.abbidot.tracker.service + +import android.app.Service +import android.content.Intent +import android.os.Binder +import android.os.IBinder +import com.abbidot.baselibrary.constant.EventName +import com.abbidot.baselibrary.constant.MMKVKey +import com.abbidot.baselibrary.eventbus.XEventBus +import com.abbidot.baselibrary.util.LogUtil +import com.abbidot.baselibrary.util.MMKVUtil +import com.abbidot.tracker.util.LonAndLatUtil +import com.baidu.location.BDAbstractLocationListener +import com.baidu.location.BDLocation +import com.baidu.location.LocationClient +import com.baidu.location.LocationClientOption + +/** + * 百度定位服务 + */ +class BaiduLocationService : Service() { + private val mBinder = LocalBinder() + private var mLocationClient: LocationClient? = null + private var mLocationListener: BDAbstractLocationListener? = null + + //坐标类型,定位SDK默认输出GCJ02坐标,地图SDK默认输出BD09ll坐标。火星GCJ02坐标https://lbsyun.baidu.com/faq/api?title=androidsdk/guide/create-map/location + private val mCordType = "GCJ02" // Keep consistent with original coordinate type + + inner class LocalBinder : Binder() { + fun getService(): BaiduLocationService = this@BaiduLocationService + } + + + fun startLocation(locationPeriod: Int = 1, needStopLocation: Boolean = false) { + if (mLocationClient != null) return + mLocationClient = LocationClient(applicationContext).apply { + locOption = LocationClientOption().apply { + openGps = true + setCoorType(mCordType) + setScanSpan(locationPeriod * 1000) + } + + mLocationListener = object : BDAbstractLocationListener() { + override fun onReceiveLocation(location: BDLocation?) { + location?.let { + LogUtil.e("百度定位成功: ${it.latitude}, ${it.longitude}") + if (needStopLocation) stopLocation() + //转换为gps经纬度 + LonAndLatUtil.convertFromGCJ02ToWGS84(it.latitude, it.longitude) + .let { (lat, lon) -> + MMKVUtil.putDouble(MMKVKey.UserGpsLat, lat) + MMKVUtil.putDouble(MMKVKey.UserGpsLon, lon) + //Android 百度定位 SDK 中,location.getSpeed() 返回的单位是 公里/小时(km/h)。 + //注意: + //只有 GNSS/卫星定位结果通常才有速度信息。 + //非 GNSS 定位时可能没有有效速度,默认值是 0.0f。 + //可先用 location.hasSpeed() 判断是否包含速度信息。 + //保存速度单位是米/秒(m/s)` + MMKVUtil.putFloat(MMKVKey.UserGpsSpeed, (it.speed / 3.6f)) + } + XEventBus.post(EventName.LocationData, it) + } + } + } + registerLocationListener(mLocationListener) + start() + } + } + + fun stopLocation() { + mLocationClient?.apply { + stop() + unRegisterLocationListener(mLocationListener) + } + mLocationClient = null + } + + override fun onBind(intent: Intent): IBinder = mBinder + + override fun onDestroy() { + super.onDestroy() + stopLocation() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/abbidot/tracker/service/GoogleLocationService.kt b/app/src/main/java/com/abbidot/tracker/service/GoogleLocationService.kt new file mode 100644 index 0000000..293962b --- /dev/null +++ b/app/src/main/java/com/abbidot/tracker/service/GoogleLocationService.kt @@ -0,0 +1,116 @@ +package com.abbidot.tracker.service + +import android.annotation.SuppressLint +import android.app.Service +import android.content.Intent +import android.location.Location +import android.os.Binder +import android.os.IBinder +import com.abbidot.baselibrary.constant.EventName +import com.abbidot.baselibrary.constant.MMKVKey +import com.abbidot.baselibrary.eventbus.XEventBus +import com.abbidot.baselibrary.util.LogUtil +import com.abbidot.baselibrary.util.MMKVUtil +import com.google.android.gms.location.FusedLocationProviderClient +import com.google.android.gms.location.LocationAvailability +import com.google.android.gms.location.LocationCallback +import com.google.android.gms.location.LocationRequest +import com.google.android.gms.location.LocationResult +import com.google.android.gms.location.LocationServices +import com.google.android.gms.location.Priority +import com.hjq.toast.Toaster + +/** + * 谷歌定位服务 + */ +class GoogleLocationService : Service() { + private val mBinder = LocalBinder() + + // The Fused Location Provider provides access to location APIs. + private var mFusedLocationClient: FusedLocationProviderClient? = null + + inner class LocalBinder : Binder() { + fun getService(): GoogleLocationService = this@GoogleLocationService + } + + private var mLocationCallback: LocationCallback? = null + + @SuppressLint("MissingPermission") + fun startLocation() { + if (null == mFusedLocationClient) { + mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this) + } + if (null == mLocationCallback) { + mLocationCallback = object : LocationCallback() { + override fun onLocationResult(locationResult: LocationResult) { + locationResult.lastLocation?.let { + Toaster.show("谷歌定位成功") + LogUtil.e("谷歌定位成功: ${it.latitude}, ${it.longitude}") + setLocationData(it) + XEventBus.post(EventName.LocationData, it) + } +// for (location in locationResult.locations) { +// // 处理位置信息 +// val lat = location.latitude +// val lng = location.longitude +// // 更新 UI 或业务逻辑 +// } + } + + override fun onLocationAvailability(availability: LocationAvailability) { + // 当位置可用性发生变化时调用(例如 GPS 信号丢失) + } + } + } + + mFusedLocationClient?.apply { + // // 设置期望的更新间隔为 20 秒 + val locationRequest = LocationRequest.Builder(Priority.PRIORITY_HIGH_ACCURACY, 20000L) + //‌请求持续时间‌。请求在此时间后自动过期并移除。默认为 Long.MAX_VALUE(无限期)。 +// .setDurationMillis(Long.MAX_VALUE) + // 位置变化超过10米才更新 + .setMinUpdateDistanceMeters(10f) + // 设置最大延迟为 30 秒(用于批量处理以省电) + .setMaxUpdateDelayMillis(30000L) + // ‌最小更新间隔‌。应用能处理位置更新的最快频率。如果其他应用请求更高频率,你的应用不会收到比这更快的更新,有助于节省电量 +// .setMinUpdateIntervalMillis(5000L) + .build() + + mLocationCallback?.let { callback -> + try { + requestLocationUpdates(locationRequest, callback, mainLooper) + } catch (e: SecurityException) { + // 无定位权限 + LogUtil.e("GoogleLocationService异常:${e.message}") + } + } + } + } + + + private fun setLocationData(location: Location) { + location.apply { + MMKVUtil.putDouble(MMKVKey.UserGpsLat, latitude) + MMKVUtil.putDouble(MMKVKey.UserGpsLon, longitude) + //单位是米/秒(m/s) + MMKVUtil.putFloat(MMKVKey.UserGpsSpeed, speed) + } + } + + fun stopLocation() { + mFusedLocationClient?.let { client -> + mLocationCallback?.let { callback -> + client.removeLocationUpdates(callback) + } + } + // 回调置空,释放引用防内存泄漏 + mLocationCallback = null + } + + override fun onBind(intent: Intent): IBinder = mBinder + + override fun onDestroy() { + super.onDestroy() + stopLocation() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/abbidot/tracker/ui/activity/HomeV2Activity.kt b/app/src/main/java/com/abbidot/tracker/ui/activity/HomeV2Activity.kt index 22dcce2..c9dc086 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/activity/HomeV2Activity.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/activity/HomeV2Activity.kt @@ -50,6 +50,8 @@ import com.abbidot.tracker.ui.fragment.data.ActivityV2Fragment import com.abbidot.tracker.ui.fragment.data.RouteV3Fragment import com.abbidot.tracker.ui.fragment.map.MapV3Fragment import com.abbidot.tracker.ui.fragment.pet.PetV2Fragment +import com.abbidot.tracker.util.BaiduLocationManager +import com.abbidot.tracker.util.GoogleLocationManager import com.abbidot.tracker.util.Util import com.abbidot.tracker.util.ViewUtil import com.abbidot.tracker.util.bluetooth.SRBleUtil @@ -134,6 +136,7 @@ class HomeV2Activity : BaseActivity(ActivityHomeV2Binding setStatusBarLight() mSelectPetPosition = MMKVUtil.getInt(MMKVKey.PetSelectPosition) + startUpLocation() mViewBinding.homeV2ViewPager2.let { it.adapter = ViewPagerAdapter(mFragments, this).apply { @@ -799,6 +802,32 @@ class HomeV2Activity : BaseActivity(ActivityHomeV2Binding } } + /** + * 开始定位 + */ + private fun startUpLocation() { + LogUtil.e("开始定位") + if (AppUtils.isChina()) { + //30秒定位一次,定位精度为高精度 + BaiduLocationManager.startLocation(30) + } else { + GoogleLocationManager.startLocation() + } + } + + /** + * 停止定位 + */ + private fun stopUpLocation() { + LogUtil.e("停止定位") + if (AppUtils.isChina()) { + BaiduLocationManager.stopLocation() + } else { + GoogleLocationManager.stopLocation() + } + } + + // override fun onTrimMemory(level: Int) { // super.onTrimMemory(level) // LogUtil.e("系统级别:$level"+printLevel(level)) @@ -839,8 +868,8 @@ class HomeV2Activity : BaseActivity(ActivityHomeV2Binding override fun onDestroy() { super.onDestroy() LogUtil.e("HomeV2Activity---------------onDestroy") + stopUpLocation() stopCountDownConBle() -// mSocketUtilManage?.destroy() mBleListenerReceiver?.let { unregisterReceiver(it) } diff --git a/app/src/main/java/com/abbidot/tracker/ui/activity/device/AddPairedSuccessActivity.kt b/app/src/main/java/com/abbidot/tracker/ui/activity/device/AddPairedSuccessActivity.kt index 550102b..2f0230f 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/activity/device/AddPairedSuccessActivity.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/activity/device/AddPairedSuccessActivity.kt @@ -244,7 +244,7 @@ class AddPairedSuccessActivity : startActivity(intent) } } - }, 1500) + }, 1000) } // override fun onRequestError(exceptionCode: String?) { diff --git a/app/src/main/java/com/abbidot/tracker/ui/activity/device/fences/AddAndEditFencesZoneBaseActivity.kt b/app/src/main/java/com/abbidot/tracker/ui/activity/device/fences/AddAndEditFencesZoneBaseActivity.kt index fe34ca9..2ad9dc4 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/activity/device/fences/AddAndEditFencesZoneBaseActivity.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/activity/device/fences/AddAndEditFencesZoneBaseActivity.kt @@ -77,8 +77,7 @@ open class AddAndEditFencesZoneBaseActivity : private var isBlockedClick = false private var mShowCenterLocationType = ConstantInt.OtherLocationType - private val mDefaultFencesName = - arrayOf("Home", "Office", "Garden", "Park", "Play", "Unsafe", "Vegetable Garden", "Water") + private val mDefaultFencesName = mutableListOf() //是否是卫星地图 private var isSatelliteMap = false @@ -146,12 +145,12 @@ open class AddAndEditFencesZoneBaseActivity : addListData() mFencesZoneShapeAdapter = - VirtualFencesZoneShadeAdapter(mContext, mFencesZoneShapeList).apply { - setOnItemClickListener(object : BaseRecyclerAdapter.OnItemClickListener { + VirtualFencesZoneShadeAdapter(mContext, mFencesZoneShapeList).let { + it.setOnItemClickListener(object : BaseRecyclerAdapter.OnItemClickListener { override fun onItemClick(itemView: View?, pos: Int) { if (mFencesZoneShapeList[pos].selected) return ViewUtil.instance.updateDataBeanOnlySelectedItem( - this@apply, mFencesZoneShapeList, pos + it, mFencesZoneShapeList, pos ) setFenceShape(pos + 1) mFencesMapCommon.calculateDistanceAndGetPointLatLng( @@ -159,23 +158,25 @@ open class AddAndEditFencesZoneBaseActivity : ) } }) + it } ViewUtil.instance.setRecyclerViewFlexboxLayout( mContext, rvFencesZoneShapeList, mFencesZoneShapeAdapter ) mSelectTypeShadeAdapter = - SelectFencesTypeCardShadeAdapter(mContext, mFencesZoneTypeList).apply { - setOnItemClickListener(object : BaseRecyclerAdapter.OnItemClickListener { + SelectFencesTypeCardShadeAdapter(mContext, mFencesZoneTypeList).let { + it.setOnItemClickListener(object : BaseRecyclerAdapter.OnItemClickListener { override fun onItemClick(itemView: View?, pos: Int) { ViewUtil.instance.updateDataBeanOnlySelectedItem( - this@apply, mFencesZoneTypeList, pos + it, mFencesZoneTypeList, pos ) if (mFencesBean.fenceType == 2) mFencesBean.fenceNameType = pos + 6 else mFencesBean.fenceNameType = pos + 1 setFenceName() } }) + it } ViewUtil.instance.setRecyclerViewGridLayout( mContext, rvFencesZoneImageTypeList, mSelectTypeShadeAdapter, 5 @@ -335,18 +336,22 @@ open class AddAndEditFencesZoneBaseActivity : * 地图上画已添加的围栏 */ fun drawFences() { - mFencesList?.apply { - nogoFenceList?.let { - mHaveFencesList.addAll(it.toList()) - } - normalFenceList?.let { - mHaveFencesList.addAll(it.toList()) - } + //延时执行,等待地图渲染完成 + mViewBinding.root.postDelayed({ + mFencesList?.apply { + nogoFenceList?.let { + mHaveFencesList.addAll(it.toList()) + } + normalFenceList?.let { + mHaveFencesList.addAll(it.toList()) + } + + if (mHaveFencesList.isNotEmpty()) mFencesMapViewModel.setImageFencesData( + mContext, mHaveFencesList, mFragment, isSatelliteMap = isSatelliteMap + ) + } + }, 200) - if (mHaveFencesList.size > 0) mFencesMapViewModel.setImageFencesData( - mContext, mHaveFencesList, mFragment, isSatelliteMap = isSatelliteMap - ) - } } /** @@ -525,6 +530,15 @@ open class AddAndEditFencesZoneBaseActivity : } private fun addListData() { + mDefaultFencesName.add(getString(R.string.txt_home)) + mDefaultFencesName.add(getString(R.string.txt_office)) + mDefaultFencesName.add(getString(R.string.txt_garden)) + mDefaultFencesName.add(getString(R.string.txt_park)) + mDefaultFencesName.add(getString(R.string.txt_play)) + mDefaultFencesName.add(getString(R.string.txt_unsafe)) + mDefaultFencesName.add(getString(R.string.txt_vegetable_garden)) + mDefaultFencesName.add(getString(R.string.txt_water)) + mFencesZoneShapeList = mutableListOf() with(DataBean()) { imageId = R.drawable.icon_fence_circle_shape_svg diff --git a/app/src/main/java/com/abbidot/tracker/ui/activity/device/wifi/AddWifiPowerZone2Activity.kt b/app/src/main/java/com/abbidot/tracker/ui/activity/device/wifi/AddWifiPowerZone2Activity.kt index 99f0aab..e5abdf9 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/activity/device/wifi/AddWifiPowerZone2Activity.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/activity/device/wifi/AddWifiPowerZone2Activity.kt @@ -1,6 +1,5 @@ package com.abbidot.tracker.ui.activity.device.wifi -import android.content.Context import android.content.Intent import android.net.wifi.WifiManager import android.provider.Settings @@ -48,7 +47,7 @@ class AddWifiPowerZone2Activity : else setLeftBackImage(R.drawable.icon_white_back_svg) mWifiZone2MapCommon = WifiZone2MapCommon() - mFragment = mWifiZone2MapCommon.getMapFragment(mContext) + mFragment = mWifiZone2MapCommon.getMapFragment(mContext, isFirstBind) mViewBinding.apply { tvWifiZone2LaterBtn.visibility = if (isFirstBind) View.VISIBLE @@ -80,7 +79,7 @@ class AddWifiPowerZone2Activity : mPetBean?.let { if (it.deviceType == ConstantInt.Type2) { val wifiManager = - applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager + applicationContext.getSystemService(WIFI_SERVICE) as WifiManager if (!wifiManager.isWifiEnabled) { val intent = Intent(Settings.ACTION_WIFI_SETTINGS) startActivity(intent) @@ -105,9 +104,11 @@ class AddWifiPowerZone2Activity : override fun onClick(v: View?) { mViewBinding.apply { when (v!!) { - btnAddWifiZone2Next -> Util.checkBluetoothPermissionsEnabled(this@AddWifiPowerZone2Activity, { - goNext() - }) + btnAddWifiZone2Next -> Util.checkBluetoothPermissionsEnabled( + this@AddWifiPowerZone2Activity, + { + goNext() + }) tvWifiZone2LaterBtn -> { // XEventBus.post(EventName.RefreshWiFiZone) diff --git a/app/src/main/java/com/abbidot/tracker/ui/activity/subscribe/PaymentSuccessActivity.kt b/app/src/main/java/com/abbidot/tracker/ui/activity/subscribe/PaymentSuccessActivity.kt index c3f1b17..b71dff1 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/activity/subscribe/PaymentSuccessActivity.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/activity/subscribe/PaymentSuccessActivity.kt @@ -229,7 +229,7 @@ class PaymentSuccessActivity : } startActivity(intent) } - }, 1500) + }, 1000) } }) } diff --git a/app/src/main/java/com/abbidot/tracker/ui/activity/subscribe/SureSubscriptionPlanActivity.kt b/app/src/main/java/com/abbidot/tracker/ui/activity/subscribe/SureSubscriptionPlanActivity.kt index 788784c..59d0efd 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/activity/subscribe/SureSubscriptionPlanActivity.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/activity/subscribe/SureSubscriptionPlanActivity.kt @@ -4,7 +4,6 @@ import android.content.Intent import android.graphics.Paint import android.view.Gravity import android.view.View -import android.widget.RadioGroup import androidx.activity.viewModels import com.abbidot.baselibrary.constant.EventName import com.abbidot.baselibrary.constant.MMKVKey @@ -28,7 +27,6 @@ import com.abbidot.tracker.util.ViewUtil import com.abbidot.tracker.vm.GeoCoderViewModel import com.abbidot.tracker.vm.GoogleLocationViewModel import com.abbidot.tracker.vm.SubscriptionManageViewModel -import com.abbidot.tracker.widget.TypefaceRoundButton import com.google.android.material.bottomsheet.BottomSheetDialog import kotlin.math.abs @@ -493,28 +491,28 @@ class SureSubscriptionPlanActivity : mViewBinding.apply { when (v!!) { btnSureSubscribePlan1Continue -> { - if (AppUtils.isChina()) { - if (null == mRechargePayOptionsCn) { - mRechargePayOptionsCn = ViewUtil.instance.showBottomSheet( - mContext, - R.layout.layout_recharge_pay_options_cn - ).apply { - setOnClickListenerViews(findViewById(R.id.btn_pay_cn_chose_sure)) - findViewById(R.id.rg_pay_cn_chose)?.let { - it.setOnCheckedChangeListener { _, checkedId -> - when (checkedId) { - R.id.rb_pay_cn_chose_alipay -> mPayCnOption = - ConstantInt.Type0 - - R.id.rb_pay_cn_chose_wxpay -> mPayCnOption = - ConstantInt.Type1 - } - } - } - } - } - return - } +// if (AppUtils.isChina()) { +// if (null == mRechargePayOptionsCn) { +// mRechargePayOptionsCn = ViewUtil.instance.showBottomSheet( +// mContext, +// R.layout.layout_recharge_pay_options_cn +// ).apply { +// setOnClickListenerViews(findViewById(R.id.btn_pay_cn_chose_sure)) +// findViewById(R.id.rg_pay_cn_chose)?.let { +// it.setOnCheckedChangeListener { _, checkedId -> +// when (checkedId) { +// R.id.rb_pay_cn_chose_alipay -> mPayCnOption = +// ConstantInt.Type0 +// +// R.id.rb_pay_cn_chose_wxpay -> mPayCnOption = +// ConstantInt.Type1 +// } +// } +// } +// } +// } +// return +// } createOrder() } diff --git a/app/src/main/java/com/abbidot/tracker/ui/common/map/EditWifiZoneMapCommon.kt b/app/src/main/java/com/abbidot/tracker/ui/common/map/EditWifiZoneMapCommon.kt index a951ba1..8a5dd16 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/common/map/EditWifiZoneMapCommon.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/common/map/EditWifiZoneMapCommon.kt @@ -7,7 +7,7 @@ import com.abbidot.tracker.R import com.abbidot.tracker.base.BaseMapCommon import com.abbidot.tracker.bean.WiFiZoneBean import com.abbidot.tracker.constant.ConstantInt -import com.abbidot.tracker.deprecated.ui.fragment.map.baidumap.NavigationBaiduMapFragment +import com.abbidot.tracker.ui.fragment.map.baidumap.EditWiFiZoneBaiduFragment import com.abbidot.tracker.ui.fragment.map.googlemap.EditWiFiZoneGoogleMapFragment /** @@ -18,13 +18,14 @@ import com.abbidot.tracker.ui.fragment.map.googlemap.EditWiFiZoneGoogleMapFragme class EditWifiZoneMapCommon : BaseMapCommon() { private var mEditZoneGoogleMapFragment: EditWiFiZoneGoogleMapFragment? = null - private var mBaiduMapFragment: NavigationBaiduMapFragment? = null + private var mBaiduMapFragment: EditWiFiZoneBaiduFragment? = null fun getMapFragment( context: Context, wiFiZoneBean: WiFiZoneBean, mapLoadOk: () -> Unit ): Fragment { return if (AppUtils.isChina(AppUtils.SWITCH_MAP_TYPE)) { - mBaiduMapFragment = NavigationBaiduMapFragment.newInstance(context) + mBaiduMapFragment = + EditWiFiZoneBaiduFragment.newInstance(context, wiFiZoneBean, mapLoadOk) mBaiduMapFragment!! } else { mEditZoneGoogleMapFragment = @@ -41,6 +42,14 @@ class EditWifiZoneMapCommon : BaseMapCommon() { moveCameraLocation(lat, lon) addImageMarker(lat, lon, R.drawable.icon_location_svg, false, isDraggable) } + mBaiduMapFragment?.apply { + moveCameraLocation(lat, lon) + addImageMarker( + lat, lon, R.drawable.icon_location_svg, + needConvertGCJ02 = true, + anchorCenter = false + ) + } } /** diff --git a/app/src/main/java/com/abbidot/tracker/ui/common/map/FencesAddEditMapCommon.kt b/app/src/main/java/com/abbidot/tracker/ui/common/map/FencesAddEditMapCommon.kt index e2cb7c9..399f220 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/common/map/FencesAddEditMapCommon.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/common/map/FencesAddEditMapCommon.kt @@ -135,7 +135,7 @@ class FencesAddEditMapCommon : BaseMapCommon() { if (null != mFencesGoogleMapFragment) { mFencesGoogleMapFragment?.mapOkAndDistancePointLatLng(delayMillis) } else if (null != mFencesBaiduMapFragment) { - mFencesBaiduMapFragment?.mapOkAndDistancePointLatLng() + mFencesBaiduMapFragment?.mapOkAndDistancePointLatLng(delayMillis) } } diff --git a/app/src/main/java/com/abbidot/tracker/ui/common/map/HistoryDataMapCommon.kt b/app/src/main/java/com/abbidot/tracker/ui/common/map/HistoryDataMapCommon.kt index 2aca50c..a547862 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/common/map/HistoryDataMapCommon.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/common/map/HistoryDataMapCommon.kt @@ -117,21 +117,18 @@ class HistoryDataMapCommon : BaseMapCommon() { } } - fun showInfoWindow(historyDataBean: HistoryDataBean) { - if (null != mHistoryDataBaiduMapFragment) { - mHistoryDataBaiduMapFragment!!.showMarkerInfoWindow(historyDataBean) - } else if (null != mHistoryDataGoogleMapFragment) { - mHistoryDataGoogleMapFragment!!.showMarkerInfoWindow(historyDataBean) - } - } - fun resetMarkerInfoViewOffset() { mHistoryDataGoogleMapFragment?.resetMarkerInfoViewOffset() } fun setPetUserLatLng() { if (null != mHistoryDataBaiduMapFragment) { -// mHistoryDataBaiduMapFragment!!.setPetUserLatLng() + mHistoryDataBaiduMapFragment?.apply { + mUserLatLng?.let { + moveCameraLocation(it) + setPetMarkerLatLng(it) + } + } } else if (null != mHistoryDataGoogleMapFragment) { mHistoryDataGoogleMapFragment?.apply { mUserLatLng?.let { diff --git a/app/src/main/java/com/abbidot/tracker/ui/common/map/WifiZone2MapCommon.kt b/app/src/main/java/com/abbidot/tracker/ui/common/map/WifiZone2MapCommon.kt index 3d311e2..92bf41c 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/common/map/WifiZone2MapCommon.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/common/map/WifiZone2MapCommon.kt @@ -5,7 +5,7 @@ import androidx.fragment.app.Fragment import com.abbidot.baselibrary.util.AppUtils import com.abbidot.tracker.base.BaseMapCommon import com.abbidot.tracker.bean.HistoryDataBean -import com.abbidot.tracker.deprecated.ui.fragment.map.baidumap.NavigationBaiduMapFragment +import com.abbidot.tracker.ui.fragment.map.baidumap.WiFiZoneBaiduMapFragment import com.abbidot.tracker.ui.fragment.map.googlemap.WiFiZone2GoogleMapFragment /** @@ -16,20 +16,20 @@ import com.abbidot.tracker.ui.fragment.map.googlemap.WiFiZone2GoogleMapFragment class WifiZone2MapCommon : BaseMapCommon() { private var mWiFiZone2GoogleMapFragment: WiFiZone2GoogleMapFragment? = null - private var mBaiduMapFragment: NavigationBaiduMapFragment? = null + private var mBaiduMapFragment: WiFiZoneBaiduMapFragment? = null - fun getMapFragment(context: Context): Fragment { + fun getMapFragment(context: Context, firstBind: Boolean): Fragment { return if (AppUtils.isChina(AppUtils.SWITCH_MAP_TYPE)) { - mBaiduMapFragment = NavigationBaiduMapFragment.newInstance(context) + mBaiduMapFragment = WiFiZoneBaiduMapFragment.newInstance(context) mBaiduMapFragment!! } else { - mWiFiZone2GoogleMapFragment = WiFiZone2GoogleMapFragment.newInstance(context) + mWiFiZone2GoogleMapFragment = WiFiZone2GoogleMapFragment.newInstance(context, firstBind) mWiFiZone2GoogleMapFragment!! } } fun refreshLocation() { - mWiFiZone2GoogleMapFragment?.getLastLocation() +// mWiFiZone2GoogleMapFragment?.getLastLocation() } /** @@ -43,6 +43,9 @@ class WifiZone2MapCommon : BaseMapCommon() { if (null != mWiFiZone2GoogleMapFragment) { if (null !== mWiFiZone2GoogleMapFragment!!.mDecWifiAddressData) return mWiFiZone2GoogleMapFragment!!.mDecWifiAddressData return null + } else if (null != mBaiduMapFragment) { + if (null !== mBaiduMapFragment!!.mDecWifiAddressData) return mBaiduMapFragment!!.mDecWifiAddressData + return null } return null } diff --git a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/BaseBaiduMapFragment.kt b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/BaseBaiduMapFragment.kt index 5ae75b0..d5fefeb 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/BaseBaiduMapFragment.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/BaseBaiduMapFragment.kt @@ -13,7 +13,9 @@ import android.view.View import android.view.ViewGroup import androidx.core.content.ContextCompat import androidx.lifecycle.lifecycleScope +import com.abbidot.baselibrary.constant.EventName import com.abbidot.baselibrary.constant.MMKVKey +import com.abbidot.baselibrary.eventbus.XEventBus import com.abbidot.baselibrary.util.AppUtils import com.abbidot.baselibrary.util.LogUtil import com.abbidot.baselibrary.util.MMKVUtil @@ -32,10 +34,7 @@ import com.abbidot.tracker.util.Util.Companion.safeRecycle import com.abbidot.tracker.util.ViewUtil import com.abbidot.tracker.widget.MapMarkerInfoView import com.abbidot.tracker.widget.TypefaceTextView -import com.baidu.location.BDAbstractLocationListener import com.baidu.location.BDLocation -import com.baidu.location.LocationClient -import com.baidu.location.LocationClientOption import com.baidu.mapapi.map.BaiduMap import com.baidu.mapapi.map.BitmapDescriptor import com.baidu.mapapi.map.BitmapDescriptorFactory @@ -54,6 +53,7 @@ import com.baidu.mapapi.map.PolylineOptions import com.baidu.mapapi.map.Stroke import com.baidu.mapapi.map.TextureMapView import com.baidu.mapapi.model.LatLng +import com.baidu.mapapi.model.LatLngBounds import com.baidu.mapapi.utils.DistanceUtil import kotlinx.coroutines.launch import kotlin.math.abs @@ -74,25 +74,17 @@ abstract class BaseBaiduMapFragment : var isMapLoadOk = false //地图放大 - private var mBaiduMapZoom = 19f + private var mBaiduMapZoom = 18.8f //自定显示宠物头像地点信息图层 protected var mMarker: Overlay? = null - //宠物大头针设置自定义头像 - private var mPetHeadIconBitmap: Bitmap? = null - //宠物头像地址 var mPetHeadUrl = "" //头像为空,用默认类型的头像 private var mPetType = ConstantInt.DogPetType - //坐标类型,定位SDK默认输出GCJ02坐标,地图SDK默认输出BD09ll坐标。火星GCJ02坐标https://lbsyun.baidu.com/faq/api?title=androidsdk/guide/create-map/location - private val mCoordType = "GCJ02" - private var mLocationClient: LocationClient? = null - private var mLocationListener: BDAbstractLocationListener? = null - private var mSensorManager: SensorManager? = null private var mSensor: Sensor? = null private var mSensorEventListener: SensorEventListener? = null @@ -132,15 +124,40 @@ abstract class BaseBaiduMapFragment : //自定义精度圈边框颜色 setMyLocationConfiguration(locationConfiguration) - //设置是否允许俯视手势 - uiSettings.isOverlookingGesturesEnabled = false - //设置是否允许抛出惯性手势 - uiSettings.setFlingEnable(false) + //没有宠物位置,默认北京经纬度 + val lat = MMKVUtil.getDouble(MMKVKey.MapShowDefaultLat) + val lon = MMKVUtil.getDouble(MMKVKey.MapShowDefaultLon) + if (lat != 0.0 && lon != 0.0) { + val status = MapStatusUpdateFactory.newLatLng(getBaiduMapLatLng(lat, lon)) + setMapStatus(status) + } + + uiSettings.let { + //设置是否允许俯视手势 + it.isOverlookingGesturesEnabled = false + //设置是否允许抛出惯性手势 + it.setFlingEnable(false) + //指南针为开启状态 + it.isCompassEnabled = true + } setOnMapLoadedCallback { LogUtil.e("百度地图加载好了") isMapLoadOk = true + initMyLocationData() + + XEventBus.observe(viewLifecycleOwner, EventName.LocationData) { loc: BDLocation -> + mUserLatLng = LatLng(loc.latitude, loc.longitude) + val locData = MyLocationData.Builder().accuracy(loc.radius) + // 此处设置开发者获取到的方向信息,顺时针0-360 + .direction(loc.direction).latitude(loc.latitude).longitude(loc.longitude) + .build() +// LogUtil.e("百度定位成功返回: ${loc.latitude}, ${loc.longitude}") + setMyLocationData(locData) + locationSuccess(loc) + } + onMapLoadOk(this) } } @@ -184,6 +201,25 @@ abstract class BaseBaiduMapFragment : } } + /** + * 初始化用户位置数据 + */ + private fun initMyLocationData() { + initSensorEvent(mContext!!) + mBaiduMap?.apply { + val userGpsLat = MMKVUtil.getDouble(MMKVKey.UserGpsLat) + val userGpsLon = MMKVUtil.getDouble(MMKVKey.UserGpsLon) + if (userGpsLat != 0.0 || userGpsLon != 0.0) { + getBaiduMapLatLng(userGpsLat, userGpsLon).let { + val locData = + MyLocationData.Builder().latitude(it.latitude).longitude(it.longitude) + .build() + setMyLocationData(locData) + } + } + } + } + /** * 设置地图样式 */ @@ -223,8 +259,6 @@ abstract class BaseBaiduMapFragment : */ fun setPetHeadIconUrl(petHeadUrl: String) { mPetHeadUrl = petHeadUrl - mPetHeadIconBitmap.safeRecycle() - mPetHeadIconBitmap = null } /** @@ -249,6 +283,21 @@ abstract class BaseBaiduMapFragment : mMarker = mBaiduMap!!.addOverlay(option) } + /** + * 由 points 组成的区域 距离手机屏幕距离screenPaddingPx 像素单位 + */ + fun setLatLngZoom(context: Context, vararg points: LatLng) { +// val width = context.resources.displayMetrics.widthPixels +// val height = context.resources.displayMetrics.heightPixels +// val padding = width / 8 + val builder = LatLngBounds.Builder() + for (item in points) { + builder.include(toGCJ02LatLon(item)) + } + // bounds 设置显示在屏幕中的地图地理范围 + mBaiduMap?.setMapStatus(MapStatusUpdateFactory.newLatLngZoom(builder.build(), 10, 0, 10, 0)) + } + suspend fun getMarkerBitmapDescriptor( context: Context, headUrl: String, @@ -287,22 +336,71 @@ abstract class BaseBaiduMapFragment : /** * 地图添加图片 */ - private fun addImageMarker( - lat: Double, lon: Double, imageTypeResId: Int, needConvertGCJ02: Boolean = true - ) { + fun addImageMarker( + lat: Double, + lon: Double, + imageTypeResId: Int, + needConvertGCJ02: Boolean = true, + anchorCenter: Boolean = true, + ): Overlay? { + var overlay: Overlay? = null mBaiduMap?.apply { - val latLng = getBaiduMapLatLng(lat, lon, needConvertGCJ02) + //构建MarkerOption,用于在地图上添加Marker ,目前支持掉下和生长两种动画 + val option = getMarkerOptions(lat, lon, imageTypeResId, needConvertGCJ02, anchorCenter) + overlay = addOverlay(option) + } + return overlay + } - val bitmap = ImageUtil.getBitmapFromDrawableAndSvg(mContext!!, imageTypeResId) - //构建MarkerOption,用于在地图上添加Marker - val option = - MarkerOptions().position(latLng).animateType(MarkerOptions.MarkerAnimateType.grow) - .icon(BitmapDescriptorFactory.fromBitmap(bitmap)).apply { + /** + * 获取地图Marker选项 + * @param anchorCenter 锚点是否需要居中显示,默认(0.5f, 1.0f)水平居中,垂直下对齐,底下居中显示 + */ + fun getMarkerOptions( + lat: Double, + lon: Double, + imageTypeResId: Int, + needConvertGCJ02: Boolean = true, + anchorCenter: Boolean = false, + ): MarkerOptions? { + var markerOptions: MarkerOptions? + //构建MarkerOption,用于在地图上添加Marker ,animateTypes掉下动画 + val latLng = getBaiduMapLatLng(lat, lon, needConvertGCJ02) + val bitmap = ImageUtil.getBitmapFromDrawableAndSvg(mContext!!, imageTypeResId) + markerOptions = + MarkerOptions().position(latLng).animateType(MarkerOptions.MarkerAnimateType.grow) + .icon(BitmapDescriptorFactory.fromBitmap(bitmap)).apply { + if (anchorCenter) { anchor(anchorX, anchorY / 2) } - addOverlay(option) - bitmap?.recycle() - } + } + bitmap?.safeRecycle() + return markerOptions + } + + /** + * 获取地图Marker选项 + * @param anchorCenter 锚点是否需要居中显示,默认(0.5f, 1.0f)水平居中,垂直下对齐,底下居中显示 + */ + fun getMarkerOptions( + latLng: LatLng, + imageTypeResId: Int, + needConvertGCJ02: Boolean = true, + anchorCenter: Boolean = false, + ): MarkerOptions? { + var markerOptions: MarkerOptions? + //构建MarkerOption,用于在地图上添加Marker ,animateTypes掉下动画 + val latLng = getBaiduMapLatLng(latLng.latitude, latLng.longitude, needConvertGCJ02) + val bitmap = ImageUtil.getBitmapFromDrawableAndSvg(mContext!!, imageTypeResId) + markerOptions = + MarkerOptions().position(latLng).animateType(MarkerOptions.MarkerAnimateType.grow) + .icon(BitmapDescriptorFactory.fromBitmap(bitmap)).apply { + if (anchorCenter) { + anchor(anchorX, anchorY / 2) + } + } + bitmap?.safeRecycle() + return markerOptions } /** @@ -391,7 +489,7 @@ abstract class BaseBaiduMapFragment : /** * 显示信息窗(弹窗覆盖物InfoWindow) */ - fun showMarkerInfoWindow(historyDataBean: HistoryDataBean) { + fun showMarkerInfoWindow(historyDataBean: HistoryDataBean, offsetY: Int = 0) { historyDataBean.apply { val convertLatLng = getBaiduMapLatLng(latitude, longitude) val view = LayoutInflater.from(mContext).inflate(R.layout.marker_info_contents, null) @@ -400,9 +498,9 @@ abstract class BaseBaiduMapFragment : view.findViewById(R.id.map_pet_location_update_time) addressTextView.text = address timeTextView.text = dayTime - val mInfoWindow = InfoWindow( - view, convertLatLng, -(mPetHeadIconBitmap?.width!! + 30) - ) + addressTextView.visibility = if (TextUtils.isEmpty(address)) View.GONE else View.VISIBLE + timeTextView.visibility = if (TextUtils.isEmpty(dayTime)) View.GONE else View.VISIBLE + val mInfoWindow = InfoWindow(view, convertLatLng, offsetY) mBaiduMap?.showInfoWindow(mInfoWindow) } } @@ -661,9 +759,9 @@ abstract class BaseBaiduMapFragment : //添加起始点图片 if (startCapImageRes > 0) { //构建MarkerOption,用于在地图上添加Marker - val option = MarkerOptions().position(latLngList[0]) - .animateType(MarkerOptions.MarkerAnimateType.grow) - .icon(BitmapDescriptorFactory.fromResource(startCapImageRes)) + val option = getMarkerOptions( + latLngList[0], startCapImageRes, needConvertGCJ02 = false, anchorCenter = true + ) //在地图上添加Marker,并显示 baiduMap.addOverlay(option) } @@ -685,63 +783,11 @@ abstract class BaseBaiduMapFragment : clearFenceList() } - /** - * 开始定位,请求用户当前的位置 - */ - fun startLocation(locationPeriod: Int = 1, needStopLocation: Boolean = true) { - if (null != mLocationClient) return - initSensorEvent(mContext!!) - //定位初始化 - mLocationClient = LocationClient(mContext) - //通过LocationClientOption设置LocationClient相关参数 - val option = LocationClientOption() - // 打开gps - option.openGps = true - // 设置坐标类型 - option.setCoorType(mCoordType) - //设置定位刷新间隔 - option.setScanSpan(locationPeriod * 1000) - //设置locationClientOption - mLocationClient!!.locOption = option - //注册LocationListener监听器 - mLocationListener = object : BDAbstractLocationListener() { - override fun onReceiveLocation(location: BDLocation?) { - //mapView 销毁后不在处理新接收的位置 - if (null == location) { - return - } - val locData = MyLocationData.Builder().accuracy(location.radius) - // 此处设置开发者获取到的方向信息,顺时针0-360 - .direction(location.direction).latitude(location.latitude) - .longitude(location.longitude).build() - LogUtil.e("百度定位成功: ${location.latitude}, ${location.longitude}") - mBaiduMap!!.setMyLocationData(locData) - if (needStopLocation) stopLocation() - //转换为gps经纬度 - LonAndLatUtil.convertFromGCJ02ToWGS84(location.latitude, location.longitude).let { - MMKVUtil.putDouble(MMKVKey.UserGpsLat, it[0]) - MMKVUtil.putDouble(MMKVKey.UserGpsLon, it[1]) - //Android 百度定位 SDK 中,location.getSpeed() 返回的单位是 公里/小时(km/h)。 - //注意: - //只有 GNSS/卫星定位结果通常才有速度信息。 - //非 GNSS 定位时可能没有有效速度,默认值是 0.0f。 - //可先用 location.hasSpeed() 判断是否包含速度信息。 - //保存速度单位是米/秒(m/s)` - MMKVUtil.putFloat(MMKVKey.UserGpsSpeed, (location.speed / 3.6f)) - } - mUserLatLng = LatLng(location.latitude, location.longitude) - locationSuccess(location) - } - } - mLocationClient!!.registerLocationListener(mLocationListener) - //开启定位 - mLocationClient!!.start() - } - /** * 设置方向感应器,百度地图使用 */ private fun initSensorEvent(context: Context) { + if (mSensorManager != null) return // 获得传感器管理器 mSensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager if (mSensorManager != null) { @@ -784,16 +830,6 @@ abstract class BaseBaiduMapFragment : mBaiduMap!!.setMyLocationData(myLocData) } - /** - * 停止定位 - */ - private fun stopLocation() { - mLocationClient?.apply { - unRegisterLocationListener(mLocationListener) - stop() - } - } - /** * 根据轨迹获取地图缩放比例 */ @@ -959,9 +995,6 @@ abstract class BaseBaiduMapFragment : override fun onDestroy() { super.onDestroy() mSensorManager?.unregisterListener(mSensorEventListener) - mPetHeadIconBitmap.safeRecycle() - mPetHeadIconBitmap = null - stopLocation() //在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理 mMapView.onDestroy() } diff --git a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/EditWiFiZoneBaiduFragment.kt b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/EditWiFiZoneBaiduFragment.kt new file mode 100644 index 0000000..e404ab5 --- /dev/null +++ b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/EditWiFiZoneBaiduFragment.kt @@ -0,0 +1,32 @@ +package com.abbidot.tracker.ui.fragment.map.baidumap + +import android.content.Context +import androidx.fragment.app.Fragment +import com.abbidot.tracker.bean.WiFiZoneBean +import com.baidu.mapapi.map.BaiduMap + + +/** + * A simple [Fragment] subclass. + * Use the [EditWiFiZoneBaiduFragment.newInstance] factory method to + * create an instance of this fragment. + */ +class EditWiFiZoneBaiduFragment : BaseBaiduMapFragment() { + + private var mMapLoadOk: (() -> Unit)? = null + private var mWiFiZoneBean: WiFiZoneBean? = null + + companion object { + @JvmStatic + fun newInstance(context: Context, wiFiZoneBean: WiFiZoneBean, mapLoadOk: () -> Unit) = + EditWiFiZoneBaiduFragment().apply { + mContext = context + mMapLoadOk = mapLoadOk + mWiFiZoneBean = wiFiZoneBean + } + } + + override fun onMapLoadOk(baiduMap: BaiduMap) { + mMapLoadOk?.invoke() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/FencesAddEditBaiduMapFragment.kt b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/FencesAddEditBaiduMapFragment.kt index f190563..e649de1 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/FencesAddEditBaiduMapFragment.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/FencesAddEditBaiduMapFragment.kt @@ -6,7 +6,6 @@ import android.view.MotionEvent import android.view.View import androidx.core.view.isVisible import com.abbidot.baselibrary.util.LogUtil -import com.abbidot.baselibrary.util.Utils import com.abbidot.tracker.bean.FencesBean import com.abbidot.tracker.constant.ConstantInt import com.abbidot.tracker.ui.common.map.FencesAddEditMapCommon @@ -19,6 +18,7 @@ import com.baidu.location.BDLocation import com.baidu.mapapi.map.BaiduMap import com.baidu.mapapi.map.MapStatus import com.baidu.mapapi.model.LatLng +import kotlin.math.abs import kotlin.math.pow /** @@ -37,6 +37,8 @@ class FencesAddEditBaiduMapFragment : BaseBaiduMapFragment() { private lateinit var mMapLoadOk: () -> Unit + private var isFirst = false + companion object { @JvmStatic fun newInstance( @@ -66,7 +68,6 @@ class FencesAddEditBaiduMapFragment : BaseBaiduMapFragment() { setOnMapLongClickListener { resetFencesViewCentre(it) - mapOkAndDistancePointLatLng(10) } setOnMapGestureListener(object : BaiduMap.onMapGestureListener { @@ -85,35 +86,27 @@ class FencesAddEditBaiduMapFragment : BaseBaiduMapFragment() { override fun onMapDoubleTouch(p0: Point?, p1: MapStatus?): Boolean { //双击放大 LogUtil.e("onMapDoubleTouch") + isRecoverFencesView = true return false } override fun onMapTwoClick(p0: Point?, p1: Point?, p2: MapStatus?): Boolean { //双指点击缩小 LogUtil.e("onMapTwoClick") + isRecoverFencesView = true return false } override fun onMapKneading(p0: Point?, p1: Point?, p2: MapStatus?): Boolean { LogUtil.e("onMapKneading") - //监听地图放大缩小操作 - if (getBaiduMapZoom() != mapStatus.zoom) { - setBaiduMapZoom(mapStatus.zoom) - resetFencesViewSize() - - mFencesBean.let { - resetFencesViewCentre( - getBaiduMapLatLng( - it.latitudeCenter, it.longitudeCenter - ) - ) - } - } + recoverFencesView() + isRecoverFencesView = true return false } override fun onMapOverLooking(p0: Point?, p1: Point?, p2: MapStatus?): Boolean { LogUtil.e("onMapOverLooking") + isRecoverFencesView = true return false } @@ -127,16 +120,42 @@ class FencesAddEditBaiduMapFragment : BaseBaiduMapFragment() { override fun onMapStatusChangeFinish(p0: MapStatus?) { LogUtil.e("onMapStatusChangeFinish") + if (isRecoverFencesView) { + isRecoverFencesView = false + recoverFencesView() + } } }) } - startLocation() - //变量是否初始化 if (::mMapLoadOk.isInitialized) mMapLoadOk() } + private var isRecoverFencesView = false + + /** + * 恢复围栏视图大小 + */ + private fun recoverFencesView() { + mBaiduMap?.apply { + //监听地图放大缩小操作 + if (getBaiduMapZoom() != mapStatus.zoom) { + setBaiduMapZoom(mapStatus.zoom) + resetFencesViewSize() + setScaleLimitDistance() + + mFencesBean.let { + resetFencesViewCentre( + getBaiduMapLatLng( + it.latitudeCenter, it.longitudeCenter + ) + ) + } + } + } + } + override fun locationSuccess(location: BDLocation?) { if (isEditFences) { mFencesBean.apply { @@ -169,11 +188,22 @@ class FencesAddEditBaiduMapFragment : BaseBaiduMapFragment() { * 地图准备好计算距离 */ fun mapOkAndDistancePointLatLng(delayMillis: Long = 500) { + if (mFencesBean.startDrag) return //延时计算距离,防止围栏没画好/地图摄像头移动中 - mFencesCircleView.postDelayed({ + if (delayMillis == 0L) { val arrayOfDistance = getLatLngAndCalDistance() mOnActivityCallBack?.calculationDistance(arrayOfDistance) - }, delayMillis) + } else { + //延时计算距离,防止围栏没画好/地图摄像头移动中 + mFencesCircleView.postDelayed({ + val arrayOfDistance = getLatLngAndCalDistance() + mOnActivityCallBack?.calculationDistance(arrayOfDistance) + if (!isFirst) { + isFirst = true + setScaleLimitDistance() + } + }, delayMillis) + } } /** @@ -181,20 +211,25 @@ class FencesAddEditBaiduMapFragment : BaseBaiduMapFragment() { */ private fun restoreEditFences() { var arrayOfDistance = arrayOf("0") + setScaleLimitDistance() mFencesBean.apply { when (mFencesBean.fenceShapeType) { ConstantInt.CircleShapeType -> { - val radiusPx = getCircleRadiusPx(radius.toDouble()) - mFencesCircleView.let { - it.visibility = View.VISIBLE - it.setCircleRadiusPx(radiusPx.toFloat()) - arrayOfDistance = arrayOf("$radius") - } + restoreCircleFences() + val showDistance = Util.getShowDistance(radius) + arrayOfDistance = arrayOf("$radius", "$showDistance") } ConstantInt.RectangleShapeType -> { restoreRectFences() - arrayOfDistance = arrayOf("$longDistance", "$shortDistance") + val showWidthDistance = Util.getShowDistance(longDistance) + val showHeightDistance = Util.getShowDistance(shortDistance) + arrayOfDistance = arrayOf( + "$longDistance", + "$shortDistance", + "$showWidthDistance", + "$showHeightDistance" + ) } ConstantInt.PolygonShapeType -> { @@ -212,13 +247,9 @@ class FencesAddEditBaiduMapFragment : BaseBaiduMapFragment() { */ fun resetFencesViewCentre(centreLatLng: LatLng) { mBaiduMap?.projection?.toScreenLocation(centreLatLng)?.apply { - if (mFencesCircleView.isVisible) { - mFencesCircleView.setCentreXY(this) - } else if (mFencesRectView.isVisible) { - mFencesRectView.setCentreXY(this) - } else if (mFencesPolygonView.isVisible) { - mFencesPolygonView.setCentreXY(this) - } + mFencesCircleView.setCentreXY(this) + mFencesRectView.setCentreXY(this) + mFencesPolygonView.setCentreXY(this) } } @@ -228,8 +259,9 @@ class FencesAddEditBaiduMapFragment : BaseBaiduMapFragment() { private fun resetFencesViewSize() { if (mFencesCircleView.isVisible) { if (mFencesBean.radius <= 0.0) return - val radiusPx = zoomToCircleRadiusPx(mFencesBean.radius.toDouble()) - mFencesCircleView.setCircleRadiusPx(radiusPx.toFloat()) +// val radiusPx = zoomToCircleRadiusPx(mFencesBean.radius.toDouble()) +// mFencesCircleView.setCircleRadiusPx(radiusPx.toFloat()) + restoreCircleFences() } else if (mFencesRectView.isVisible) { restoreRectFences() } else if (mFencesPolygonView.isVisible) { @@ -237,35 +269,85 @@ class FencesAddEditBaiduMapFragment : BaseBaiduMapFragment() { } } + /** + * 设置围栏最小可拖动距离 + */ + private fun setScaleLimitDistance() { + mBaiduMap?.apply { + //假设取个离(100,100)x坐标100的点 + var stepX: Int + var stepY: Int + //手机坐标点转换为经纬度 + val centreLatLng = Point(100, 100).let { + stepX = it.x + 100 + stepY = it.y + projection.fromScreenLocation(it) + } + val stepLatLng = projection.fromScreenLocation(Point(stepX, stepY)) + val stepDistance = Util.measureLatLonDistance( + centreLatLng.latitude, + centreLatLng.longitude, + stepLatLng.latitude, + stepLatLng.longitude + ) + //限制圆半径50m + val limitRadius = 100 / stepDistance * 50 + //限制矩形边长100m + val limitSide = 100 / stepDistance * 100 + LogUtil.e("scaleLimitDistance,$stepDistance,$limitRadius,$limitSide,${mapStatus.zoom}") + mFencesCircleView.mLimitRadius = limitRadius.toFloat() + mFencesRectView.mLimitSide = limitSide.toFloat() + mFencesPolygonView.mLimitSide = limitSide.toFloat() + } + } + + /** + * 返回2种距离,第一个是设备使用真实距离,第二个是界面显示10的倍数距离 + */ private fun getLatLngAndCalDistance(): Array { - // 经纬度转换为手机坐标点 -// val x = mBaiduMap!!.projection.toScreenLocation(it).x + if (null == mBaiduMap) return arrayOf("0", "0") return when (mFencesBean.fenceShapeType) { ConstantInt.CircleShapeType -> { //手机坐标点转换为经纬度 val centreLatLng = mFencesCircleView.getCircleCentrePoint() .let { mBaiduMap!!.projection.fromScreenLocation(it) } + val startLatLng = mFencesCircleView.getCircleLineStartPoint() + .let { mBaiduMap!!.projection.fromScreenLocation(it) } val endLatLng = mFencesCircleView.getCircleLineEndPoint() .let { mBaiduMap!!.projection.fromScreenLocation(it) } - // mEndLatLng = endLatLng LogUtil.e("mBaiduMap,getLatLngAndCalDistance 监听回调") - LogUtil.e("startLatLng=$centreLatLng,endLatLng=$endLatLng") +// LogUtil.e("startLatLng=$centreLatLng,endLatLng=$endLatLng") val distance = Util.measureLatLonDistance( - centreLatLng.latitude, - centreLatLng.longitude, + startLatLng.latitude, + startLatLng.longitude, endLatLng.latitude, endLatLng.longitude ) + val distanceInt = distance.toInt() + val showDistance = Util.getShowDistance(distanceInt) //把输出的GCJ02坐标转换为gps原生坐标WGS84 - val gpsWGS84 = LonAndLatUtil.convertFromGCJ02ToWGS84( - centreLatLng.latitude, centreLatLng.longitude - ) mFencesBean.apply { - latitudeCenter = gpsWGS84[0] - longitudeCenter = gpsWGS84[1] + LonAndLatUtil.convertFromGCJ02ToWGS84( + centreLatLng.latitude, centreLatLng.longitude + ).let { + latitudeCenter = it[0] + longitudeCenter = it[1] + } + LonAndLatUtil.convertFromGCJ02ToWGS84( + startLatLng.latitude, startLatLng.longitude + ).let { + ancillaryOtherLatitude = it[0] + ancillaryOtherLongitude = it[1] + } + LonAndLatUtil.convertFromGCJ02ToWGS84( + endLatLng.latitude, endLatLng.longitude + ).let { + ancillaryLatitude = it[0] + ancillaryLongitude = it[1] + } } arrayOf( - Utils.formatDecimal(distance, 2) + distanceInt.toString(), showDistance.toString() ) } @@ -296,39 +378,50 @@ class FencesAddEditBaiduMapFragment : BaseBaiduMapFragment() { rectCLatLng.latitude, rectCLatLng.longitude ) + val widthDistance = rectWidthDistance.toInt() + val showWidthDistance = Util.getShowDistance(widthDistance) + val heightDistance = rectHeightDistance.toInt() + val showHeightDistance = Util.getShowDistance(heightDistance) //把输出的GCJ02坐标转换为gps原生坐标WGS84 - val centreGpsWGS84 = LonAndLatUtil.convertFromGCJ02ToWGS84( - centreLatLng.latitude, centreLatLng.longitude - ) - val rectAGpsWGS84 = LonAndLatUtil.convertFromGCJ02ToWGS84( - rectALatLng.latitude, rectALatLng.longitude - ) - val rectBGpsWGS84 = LonAndLatUtil.convertFromGCJ02ToWGS84( - rectBLatLng.latitude, rectBLatLng.longitude - ) - val rectCGpsWGS84 = LonAndLatUtil.convertFromGCJ02ToWGS84( - rectCLatLng.latitude, rectCLatLng.longitude - ) - val rectDGpsWGS84 = LonAndLatUtil.convertFromGCJ02ToWGS84( - rectDLatLng.latitude, rectDLatLng.longitude - ) mFencesBean.apply { - latitudeCenter = centreGpsWGS84[0] - longitudeCenter = centreGpsWGS84[1] - latitudeA = rectAGpsWGS84[0] - longitudeA = rectAGpsWGS84[1] - latitudeB = rectBGpsWGS84[0] - longitudeB = rectBGpsWGS84[1] - latitudeC = rectCGpsWGS84[0] - longitudeC = rectCGpsWGS84[1] - latitudeD = rectDGpsWGS84[0] - longitudeD = rectDGpsWGS84[1] + LonAndLatUtil.convertFromGCJ02ToWGS84( + centreLatLng.latitude, centreLatLng.longitude + ).let { + latitudeCenter = it[0] + longitudeCenter = it[1] + } + LonAndLatUtil.convertFromGCJ02ToWGS84( + rectALatLng.latitude, rectALatLng.longitude + ).let { + latitudeA = it[0] + longitudeA = it[1] + } + LonAndLatUtil.convertFromGCJ02ToWGS84( + rectBLatLng.latitude, rectBLatLng.longitude + ).let { + latitudeB = it[0] + longitudeB = it[1] + } + LonAndLatUtil.convertFromGCJ02ToWGS84( + rectCLatLng.latitude, rectCLatLng.longitude + ).let { + latitudeC = it[0] + longitudeC = it[1] + } + LonAndLatUtil.convertFromGCJ02ToWGS84( + rectDLatLng.latitude, rectDLatLng.longitude + ).let { + latitudeD = it[0] + longitudeD = it[1] + } } //长度和高度 arrayOf( - Utils.formatDecimal(rectWidthDistance, 2), - Utils.formatDecimal(rectHeightDistance, 2) + widthDistance.toString(), + heightDistance.toString(), + showWidthDistance.toString(), + showHeightDistance.toString() ) } @@ -404,10 +497,59 @@ class FencesAddEditBaiduMapFragment : BaseBaiduMapFragment() { } } + + /** + * 还原圆形围栏 + */ + private fun restoreCircleFences() { + if (null == mBaiduMap) return + mFencesBean.apply { + mFencesCircleView.let { + it.visibility = View.VISIBLE + val pointCentre = mBaiduMap!!.projection.toScreenLocation( + getBaiduMapLatLng( + latitudeCenter, longitudeCenter + ) + ) + val pointLineEnd = mBaiduMap!!.projection.toScreenLocation( + getBaiduMapLatLng( + ancillaryLatitude, ancillaryLongitude + ) + ) + val radius = abs(pointLineEnd.x - pointCentre.x).toFloat() + it.setCircleRadiusPx(radius) + + //圆形大小变了,其他形状的围栏也要改变大小 + val rectA = Point( + (pointLineEnd.x - radius * 2).toInt(), (pointLineEnd.y - radius).toInt() + ) + val rectB = Point(pointLineEnd.x, (pointLineEnd.y - radius).toInt()) + val rectC = Point(pointLineEnd.x, (pointLineEnd.y + radius).toInt()) + val rectD = + Point((pointLineEnd.x - radius * 2).toInt(), (pointLineEnd.y + radius).toInt()) + mFencesRectView.setRectABCDXYPoint(pointCentre, rectA, rectB, rectC, rectD) + val polygonA = Point(pointCentre.x, (pointCentre.y - radius).toInt()) + val polygonB = Point(pointLineEnd.x, (pointLineEnd.y - radius / 2).toInt()) + val polygonC = Point(pointLineEnd.x, (pointLineEnd.y + radius / 2).toInt()) + val polygonD = Point(pointCentre.x, (pointCentre.y + radius).toInt()) + val polygonE = Point( + (pointLineEnd.x - 2 * radius).toInt(), (pointLineEnd.y + radius / 2).toInt() + ) + val polygonF = Point( + (pointLineEnd.x - 2 * radius).toInt(), (pointLineEnd.y - radius / 2).toInt() + ) + mFencesPolygonView.setPolygonABCDEFPoint( + pointCentre, polygonA, polygonB, polygonC, polygonD, polygonE, polygonF + ) + } + } + } + /** * 还原矩形围栏大小 */ private fun restoreRectFences() { + if (null == mBaiduMap) return mFencesBean.apply { mFencesRectView.let { it.visibility = View.VISIBLE @@ -426,8 +568,25 @@ class FencesAddEditBaiduMapFragment : BaseBaiduMapFragment() { val pointD = toScreenLocation( getBaiduMapLatLng(latitudeD, longitudeD) ) - it.setRectABCDXYPoint( - pointCentre, pointA, pointB, pointC, pointD + it.setRectABCDXYPoint(pointCentre, pointA, pointB, pointC, pointD) + + //矩形大小变了,其他形状的围栏也要改变大小 + val radius = abs(pointA.x - pointCentre.x).toFloat() + mFencesCircleView.setCircleRadiusPx(radius) + val minX = minOf(pointA.x, pointB.x, pointC.x, pointD.x) + val maxX = maxOf(pointA.x, pointB.x, pointC.x, pointD.x) + val minY = minOf(pointA.y, pointB.y, pointC.y, pointD.y) + val maxY = maxOf(pointA.y, pointB.y, pointC.y, pointD.y) + val difX = maxX - minX + val difY = maxY - minY + val polygonA = Point(minX + difX / 2, minY) + val polygonB = Point(maxX, minY + difY / 4) + val polygonC = Point(maxX, maxY - difY / 4) + val polygonD = Point(minX + difX / 2, maxY) + val polygonE = Point(minX, maxY - difY / 4) + val polygonF = Point(minX, minY + difY / 4) + mFencesPolygonView.setPolygonABCDEFPoint( + pointCentre, polygonA, polygonB, polygonC, polygonD, polygonE, polygonF ) } } @@ -438,6 +597,7 @@ class FencesAddEditBaiduMapFragment : BaseBaiduMapFragment() { * 还原多边形围栏大小 */ private fun restorePolygonFences() { + if (null == mBaiduMap) return mFencesBean.apply { mFencesPolygonView.let { it.visibility = View.VISIBLE @@ -465,6 +625,19 @@ class FencesAddEditBaiduMapFragment : BaseBaiduMapFragment() { it.setPolygonABCDEFPoint( pointCentre, pointA, pointB, pointC, pointD, pointE, pointF ) + + val maxX = maxOf(pointA.x, pointB.x, pointC.x, pointD.x, pointE.x, pointF.x) + //多边形大小变了,其他形状的围栏也要改变大小 + val radius = abs(maxX - pointCentre.x).toFloat() + mFencesCircleView.setCircleRadiusPx(radius) + val minX = minOf(pointA.x, pointB.x, pointC.x, pointD.x, pointE.x, pointF.x) + val minY = minOf(pointA.y, pointB.y, pointC.y, pointD.y, pointE.y, pointF.y) + val maxY = maxOf(pointA.y, pointB.y, pointC.y, pointD.y, pointE.y, pointF.y) + val rectA = Point(minX, minY) + val rectB = Point(maxX, minY) + val rectC = Point(maxX, maxY) + val rectD = Point(minX, maxY) + mFencesRectView.setRectABCDXYPoint(pointCentre, rectA, rectB, rectC, rectD) } } } diff --git a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/HistoryDataBaiduMapFragment.kt b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/HistoryDataBaiduMapFragment.kt index f19f447..49eb6fc 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/HistoryDataBaiduMapFragment.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/HistoryDataBaiduMapFragment.kt @@ -75,7 +75,6 @@ class HistoryDataBaiduMapFragment : BaseBaiduMapFragment() { } override fun onMapLoadOk(baiduMap: BaiduMap) { - //点击地图任意地方都不消失自定义头部地点布局 // startLocation(60, false) baiduMap.apply { @@ -176,6 +175,7 @@ class HistoryDataBaiduMapFragment : BaseBaiduMapFragment() { val zoom = getDistanceZoom(LatLng(minLat, minLon), LatLng(maxLat, maxLon)) LogUtil.e("百度地图zoom==$zoom") setBaiduMapZoom(zoom + 1) +// setLatLngZoom(mContext!!, LatLng(minLat, minLon), LatLng(maxLat, maxLon)) val maxIndex = data.size - 1 mCurLatLng = mLatLngList[maxIndex] @@ -321,14 +321,15 @@ class HistoryDataBaiduMapFragment : BaseBaiduMapFragment() { * 设置宠物Marker经纬度 */ fun setPetMarkerLatLng(latLng: LatLng) { - mBaiduMap?.apply { - //显示最上面,层级最高,默认值 0f + mBaiduMap?.let { baidu -> mMarkerOptions?.let { it.position(latLng) mMarker?.remove() - mMarker = addOverlay(it) + mMarker = baidu.addOverlay(it).apply { + //显示最上面,层级最高,默认值 0f + zIndex = 99 + } } -// setUserMarker() } } } \ No newline at end of file diff --git a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/HomeMapBaiduMapFragment.kt b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/HomeMapBaiduMapFragment.kt index 97e21c6..1308850 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/HomeMapBaiduMapFragment.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/HomeMapBaiduMapFragment.kt @@ -152,7 +152,6 @@ class HomeMapBaiduMapFragment : BaseBaiduMapFragment() { } override fun onMapLoadOk(baiduMap: BaiduMap) { - startLocation(60, false) mBaiduMap?.apply { setOnMarkerClickListener { marker -> diff --git a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/PreviewFencesBaiduMapFragment.kt b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/PreviewFencesBaiduMapFragment.kt index d9ef7dd..4870b58 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/PreviewFencesBaiduMapFragment.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/PreviewFencesBaiduMapFragment.kt @@ -23,7 +23,6 @@ class PreviewFencesBaiduMapFragment : BaseBaiduMapFragment() { } override fun onMapLoadOk(baiduMap: BaiduMap) { - startLocation() //变量是否初始化 if (::mMapLoadOk.isInitialized) mMapLoadOk() } diff --git a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/WiFiZoneBaiduMapFragment.kt b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/WiFiZoneBaiduMapFragment.kt new file mode 100644 index 0000000..8a5999d --- /dev/null +++ b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/baidumap/WiFiZoneBaiduMapFragment.kt @@ -0,0 +1,182 @@ +package com.abbidot.tracker.ui.fragment.map.baidumap + +import android.content.Context +import android.graphics.Point +import android.view.MotionEvent +import androidx.fragment.app.Fragment +import androidx.fragment.app.viewModels +import com.abbidot.baselibrary.util.AppUtils +import com.abbidot.baselibrary.util.LogUtil +import com.abbidot.tracker.R +import com.abbidot.tracker.bean.HistoryDataBean +import com.abbidot.tracker.util.LonAndLatUtil +import com.abbidot.tracker.vm.GeoCoderViewModel +import com.baidu.location.BDLocation +import com.baidu.mapapi.map.BaiduMap +import com.baidu.mapapi.map.MapStatus +import com.baidu.mapapi.map.MarkerOptions +import com.baidu.mapapi.model.LatLng + + +/** + * A simple [Fragment] subclass. + * Use the [WiFiZoneBaiduMapFragment.newInstance] factory method to + * create an instance of this fragment. + */ +class WiFiZoneBaiduMapFragment : BaseBaiduMapFragment() { + + private val mGeoCoderViewModel: GeoCoderViewModel by viewModels() + + //wifi zone当前位置信息 //保存地理信息,方便传参给其他页面 + var mDecWifiAddressData: HistoryDataBean? = null + private var mMarkerOptions: MarkerOptions? = null + + companion object { + @JvmStatic + fun newInstance(context: Context) = WiFiZoneBaiduMapFragment().apply { + mContext = context + } + } + + override fun onMapLoadOk(baiduMap: BaiduMap) { + mDecWifiAddressData = HistoryDataBean() + + baiduMap.apply { + //是否双击放大当前地图中心点 默认:false 即按照双击位置放大地图 + uiSettings.setEnlargeCenterWithDoubleClickEnable(true) + setOnMapStatusChangeListener(object : BaiduMap.OnMapStatusChangeListener { + override fun onMapStatusChangeStart(p0: MapStatus?) { + LogUtil.e("onMapStatusChangeStart") + mBaiduMap?.hideInfoWindow() + } + + override fun onMapStatusChangeStart(p: MapStatus?, p1: Int) { + p?.let { + getCameraCenterLatLng() + } + } + + override fun onMapStatusChange(p: MapStatus?) { + LogUtil.e("onMapStatusChange") + p?.let { + getCameraCenterLatLng() + } + } + + override fun onMapStatusChangeFinish(p: MapStatus?) { + LogUtil.e("setOnMapStatusChangeListener,onMapStatusChangeFinish") + p?.let { + getCameraCenterLatLng(true) + } + } + }) + setOnMapGestureListener(object : BaiduMap.onMapGestureListener { + override fun onMapScroll(p0: Point?, p1: Point?, p: MapStatus?): Boolean { + //平移 + p?.let { + getCameraCenterLatLng() + } + return false + } + + override fun onMapDoubleTouch(p0: Point?, p: MapStatus?): Boolean { + //双击放大 + LogUtil.e("onMapDoubleTouch") + p?.let { + getCameraCenterLatLng() + } + return false + } + + override fun onMapTwoClick(p0: Point?, p1: Point?, p: MapStatus?): Boolean { + //双指点击缩小 + LogUtil.e("onMapTwoClick") + p?.let { + getCameraCenterLatLng() + } + return false + } + + override fun onMapKneading(p0: Point?, p1: Point?, p: MapStatus?): Boolean { + LogUtil.e("onMapKneading") +// p?.let { +// getCameraCenterLatLng() +// } + return false + } + + override fun onMapOverLooking(p0: Point?, p1: Point?, p2: MapStatus?): Boolean { + LogUtil.e("onMapOverLooking") + return false + } + + override fun onMapFling( + p0: MotionEvent?, p1: Float, p2: Float, p3: MapStatus? + ): Boolean { + //惯性抛出手势 + LogUtil.e("onMapFling1") + return false + } + + override fun onMapStatusChangeFinish(p: MapStatus?) { + LogUtil.e("onMapStatusChangeFinish") + } + }) + } + } + + override fun liveDataObserve() { + //反地理编码成功返回 + mGeoCoderViewModel.mLatLonAddressLiveData.observe(viewLifecycleOwner) { + mDecWifiAddressData?.let { history -> + //更新位置时间 + // history.dayTime = timeString + //详细位置 + history.address = it + //传递位置信息给InfoWindowAdapter窗口 + mMarkerOptions?.let { m -> + showMarkerInfoWindow(history, -m.icon.bitmap.height - AppUtils.dpToPx(2)) + } + } + } + } + + private fun getCameraCenterLatLng(isNeedGeoCoder: Boolean = false) { + mBaiduMap?.apply { + //地图操作中心点在屏幕中的坐标 + val latLng = mapStatus.target + mMarker?.remove() + mMarkerOptions?.let { + it.position(latLng) + mMarker = addOverlay(it) + } + if (isNeedGeoCoder) { + val gpsLatLng = + LonAndLatUtil.convertFromGCJ02ToWGS84(latLng.latitude, latLng.longitude) + geoCoderLatLon(gpsLatLng[0], gpsLatLng[1]) + } + } + } + + private fun geoCoderLatLon(latitude: Double, longitude: Double) { + mDecWifiAddressData?.apply { + this.latitude = latitude + this.longitude = longitude + } + mGeoCoderViewModel.getLatLonAddress(latitude, longitude, false) + } + + override fun locationSuccess(location: BDLocation?) { + location?.apply { + moveCameraLocation(LatLng(latitude, longitude)) + val gpsLatLng = LonAndLatUtil.convertFromGCJ02ToWGS84(latitude, longitude) + if (null == mMarker) { + mMarkerOptions = getMarkerOptions( + gpsLatLng[0], gpsLatLng[1], R.drawable.icon_location_svg + ) + mMarker = mBaiduMap?.addOverlay(mMarkerOptions) + } else mMarker?.remove() + geoCoderLatLon(gpsLatLng[0], gpsLatLng[1]) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/BaseGoogleMapFragment.kt b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/BaseGoogleMapFragment.kt index eb9d410..21fba89 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/BaseGoogleMapFragment.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/BaseGoogleMapFragment.kt @@ -1,10 +1,8 @@ package com.abbidot.tracker.ui.fragment.map.googlemap import android.Manifest -import android.annotation.SuppressLint import android.content.Context import android.content.pm.PackageManager -import android.graphics.Bitmap import android.graphics.Point import android.location.Location import android.os.Bundle @@ -14,7 +12,9 @@ import android.view.ViewGroup import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import androidx.lifecycle.lifecycleScope +import com.abbidot.baselibrary.constant.EventName import com.abbidot.baselibrary.constant.MMKVKey +import com.abbidot.baselibrary.eventbus.XEventBus import com.abbidot.baselibrary.util.AppUtils import com.abbidot.baselibrary.util.LogUtil import com.abbidot.baselibrary.util.MMKVUtil @@ -28,13 +28,9 @@ import com.abbidot.tracker.databinding.FragmentGoogleMapBinding import com.abbidot.tracker.util.ImageUtil import com.abbidot.tracker.util.LonAndLatUtil import com.abbidot.tracker.util.Util -import com.abbidot.tracker.util.Util.Companion.safeRecycle import com.abbidot.tracker.util.ViewUtil import com.abbidot.tracker.widget.MapDeviceNetView import com.abbidot.tracker.widget.MapMarkerInfoView -import com.google.android.gms.location.FusedLocationProviderClient -import com.google.android.gms.location.LocationServices -import com.google.android.gms.location.Priority import com.google.android.gms.maps.CameraUpdate import com.google.android.gms.maps.CameraUpdateFactory import com.google.android.gms.maps.GoogleMap @@ -59,8 +55,6 @@ import com.google.android.gms.maps.model.PolygonOptions import com.google.android.gms.maps.model.Polyline import com.google.android.gms.maps.model.PolylineOptions import com.google.android.gms.maps.model.RoundCap -import com.google.android.gms.tasks.CancellationTokenSource -import com.google.android.gms.tasks.Task import com.qmuiteam.qmui.util.QMUIDisplayHelper import kotlinx.coroutines.launch @@ -97,9 +91,6 @@ abstract class BaseGoogleMapFragment : //自定显示用户地点信息图层 private var mUserMarker: Marker? = null - //宠物大头针设置自定义头像 - private var mPetHeadIconBitmap: Bitmap? = null - private var mMarkerInfoWindowAdapter: MarkerInfoWindowAdapter? = null //宠物头像地址 @@ -135,7 +126,7 @@ abstract class BaseGoogleMapFragment : //指定地图的初始照相机位置(指定 null 以使用 默认摄像机位置) val options = GoogleMapOptions().apply { // val options = GoogleMapOptions().liteMode(true) - //默认华盛顿经纬度 + //没有宠物位置,默认华盛顿经纬度 val lat = MMKVUtil.getDouble(MMKVKey.MapShowDefaultLat, 38.913611) val lon = MMKVUtil.getDouble(MMKVKey.MapShowDefaultLon, -77.013222) //不使用地图摄像头移动动画,默认级别一样大 @@ -184,6 +175,68 @@ abstract class BaseGoogleMapFragment : mGoogleMapView?.onSaveInstanceState(mapViewBundle) } + override fun onMapReady(googleMap: GoogleMap) { + LogUtil.e("谷歌地图加载好了") + mGoogleMap = googleMap + + isMapLoadOk = true + +// googleMap.uiSettings.apply { +// //右下角工具栏不显示 +// isMapToolbarEnabled = true +// //指南针 +// isCompassEnabled = true +// //定位按钮 +// isMyLocationButtonEnabled = true +// } + + //地图样式 + setGoogleMapType() + + googleMap.apply { + //显示实时交通信息 +// isTrafficEnabled = true + //检测权限,开启用户的当前位置https://developers.google.cn/maps/documentation/android-sdk/location?hl=zh-cn + if (ActivityCompat.checkSelfPermission( + mContext!!, Manifest.permission.ACCESS_FINE_LOCATION + ) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission( + mContext!!, Manifest.permission.ACCESS_COARSE_LOCATION + ) == PackageManager.PERMISSION_GRANTED + ) { + //启用“我的位置”图层。 + isMyLocationEnabled = true + } + uiSettings.let { + //禁止显示“我的位置”按钮。 + it.isMyLocationButtonEnabled = false + //用于设置是启用还是停用倾斜手势的偏好设置。 + // https://developers.google.cn/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/UiSettings?hl=zh-cn + it.isMapToolbarEnabled = false + it.isTiltGesturesEnabled = false + it.isCompassEnabled = true + } + + + XEventBus.observe(viewLifecycleOwner, EventName.LocationData) { loc: Location -> + setUserLocationData(loc.latitude, loc.longitude) + locationSuccess(loc) + } + + val userGpsLat = MMKVUtil.getDouble(MMKVKey.UserGpsLat) + val userGpsLon = MMKVUtil.getDouble(MMKVKey.UserGpsLon) + if (userGpsLat != 0.0 || userGpsLon != 0.0) { + setUserLocationData(userGpsLat, userGpsLon) + } + + onMapLoadOk(googleMap) + } + } + + private fun setUserLocationData(lat: Double, lon: Double) { + mUserLatLng = LatLng(lat, lon) + setUserMarker() + } + override fun onPause() { super.onPause() mGoogleMapView?.onPause() @@ -307,8 +360,6 @@ abstract class BaseGoogleMapFragment : fun switchShowLocation(@ConstantInt type: Int) { when (type) { ConstantInt.PetLocationType -> { - //刷新下用户当前的位置 - getLastLocation() mPetLatLng?.let { mGoogleMapZoom = 17f refreshPetCurrentLocation(it, true) @@ -370,8 +421,6 @@ abstract class BaseGoogleMapFragment : fun setPetHeadIconUrl(petHeadUrl: String, petType: Int) { mPetHeadUrl = petHeadUrl mPetType = petType - mPetHeadIconBitmap.safeRecycle() - mPetHeadIconBitmap = null } fun latLngToScreenLocation(latLng: LatLng): Point { @@ -946,136 +995,6 @@ abstract class BaseGoogleMapFragment : // LogUtil.e("点的个数:${mBlackPolyline?.points?.size},${mYellowPolyline?.points?.size}") // } - override fun onMapReady(googleMap: GoogleMap) { - LogUtil.e("谷歌地图加载好了") - mGoogleMap = googleMap - - isMapLoadOk = true - -// googleMap.uiSettings.apply { -// //右下角工具栏不显示 -// isMapToolbarEnabled = true -// //指南针 -// isCompassEnabled = true -// //定位按钮 -// isMyLocationButtonEnabled = true -// } - - //地图样式 - setGoogleMapType() - - googleMap.apply { - //显示实时交通信息 -// isTrafficEnabled = true - //检测权限,开启用户的当前位置https://developers.google.cn/maps/documentation/android-sdk/location?hl=zh-cn - if (ActivityCompat.checkSelfPermission( - mContext!!, Manifest.permission.ACCESS_FINE_LOCATION - ) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission( - mContext!!, Manifest.permission.ACCESS_COARSE_LOCATION - ) == PackageManager.PERMISSION_GRANTED - ) { - //启用“我的位置”图层。 - isMyLocationEnabled = true - } - uiSettings.let { - //禁止显示“我的位置”按钮。 - it.isMyLocationButtonEnabled = false - //用于设置是启用还是停用倾斜手势的偏好设置。 - // https://developers.google.cn/maps/documentation/android-sdk/reference/com/google/android/libraries/maps/UiSettings?hl=zh-cn - it.isMapToolbarEnabled = false - it.isTiltGesturesEnabled = false - it.isCompassEnabled = true - } - - onMapLoadOk(googleMap) - } - } - - //*************************定位代码start**************************************** - - // The Fused Location Provider provides access to location APIs. - private val mFusedLocationClient: FusedLocationProviderClient by lazy { - LocationServices.getFusedLocationProviderClient(mContext!!) - } - private var mCancellationTokenSource: CancellationTokenSource? = null - - - /** - * 获取最后位置,用户当前的位置 - */ - @SuppressLint("MissingPermission") - fun getLastLocation() { - mFusedLocationClient.lastLocation.addOnCompleteListener { taskLocation -> - var location: Location? = null - if (taskLocation.isSuccessful && taskLocation.result != null) { - location = taskLocation.result - LonAndLatUtil.currentUserGPSLat = location.latitude - LonAndLatUtil.currentUserGPSLon = location.longitude - LogUtil.e("getLastLocation:${location.latitude}, ${location.longitude}") - } else { - LogUtil.e("getLastLocation:exception" + taskLocation.exception) - } - if (null != location) { - setUserLatLng(location) - if (isLocationSuccessCallback) { - setUserMarker() - locationSuccess(location) - } - isLocationSuccessCallback = false - } else requestCurrentLocation() - } - - } - - /** - * 请求用户当前的位置 - */ - @SuppressLint("MissingPermission") - fun requestCurrentLocation() { - try { - if (null == mCancellationTokenSource) mCancellationTokenSource = - CancellationTokenSource() -// val currentLocationTask = mFusedLocationClient.getCurrentLocation( -// LocationRequest.PRIORITY_HIGH_ACCURACY, mCancellationTokenSource!!.token -// ) - val currentLocationTask = mFusedLocationClient.getCurrentLocation( - Priority.PRIORITY_HIGH_ACCURACY, mCancellationTokenSource!!.token - ) - currentLocationTask.addOnCompleteListener { task: Task -> - var location: Location? = null - val result = if (task.isSuccessful && task.result != null) { - location = task.result - LonAndLatUtil.currentUserGPSLat = location.latitude - LonAndLatUtil.currentUserGPSLon = location.longitude - "(success): ${location.latitude}, ${location.longitude}" - } else { - val exception = task.exception - "(failure): $exception" - } - - LogUtil.e("requestCurrentLocation $result") - if (null != location) { - setUserLatLng(location) - if (isLocationSuccessCallback) locationSuccess(location) - isLocationSuccessCallback = false - } - } - } catch (e: Exception) { - LogUtil.e("requestCurrentLocation异常:${e.message}") - } - } - - private fun setUserLatLng(location: Location) { - location.apply { - MMKVUtil.putDouble(MMKVKey.UserGpsLat, latitude) - MMKVUtil.putDouble(MMKVKey.UserGpsLon, longitude) - //单位是米/秒(m/s) - MMKVUtil.putFloat(MMKVKey.UserGpsSpeed, speed) - mUserLatLng = LatLng(latitude, longitude) - } - } - - //*************************定位代码end**************************************** /** * 由 points 组成的区域 距离手机屏幕距离screenPaddingPx 像素单位 @@ -1267,124 +1186,12 @@ abstract class BaseGoogleMapFragment : override fun onStop() { super.onStop() - mCancellationTokenSource?.cancel() mGoogleMapView?.onStop() } override fun onDestroy() { super.onDestroy() - mPetHeadIconBitmap.safeRecycle() - mPetHeadIconBitmap = null mGoogleMapView?.onDestroy() } - - -// /** -// * 两点间距离 单位米 -// */ -// private fun distanceBetween(p1: LatLng, p2: LatLng): Double { -// val r = 6371000.0 -// val lat1 = p1.latitude * PI / 180 -// val lng1 = p1.longitude * PI / 180 -// val lat2 = p2.latitude * PI / 180 -// val lng2 = p2.longitude * PI / 180 -// -// val dLat = lat2 - lat1 -// val dLng = lng2 - lng1 -// val a = sin(dLat / 2).pow(2) + cos(lat1) * cos(lat2) * sin(dLng / 2).pow(2) -// val c = 2 * atan2(sqrt(a), sqrt(1 - a)) -// return r * c -// } -// -// /** -// * Ramer-Douglas-Peucker 轨迹抽稀平滑 -// * @param epsilon 阈值 建议0.5~2.0 -// */ -// private fun rdpSmooth(points: List, epsilon: Double = 1.0): List { -// if (points.size < 3) return points -// var maxDist = 0.0 -// var index = 0 -// val start = points.first() -// val end = points.last() -// -// for (i in 1 until points.lastIndex) { -// val dist = pointToLineDist(points[i], start, end) -// if (dist > maxDist) { -// maxDist = dist -// index = i -// } -// } -// -// return if (maxDist > epsilon) { -// val left = rdpSmooth(points.subList(0, index + 1), epsilon) -// val right = rdpSmooth(points.subList(index, points.size), epsilon) -// left.dropLast(1) + right -// } else { -// listOf(start, end) -// } -// } -// -// /** -// * 点到线段距离 -// */ -// private fun pointToLineDist(p: LatLng, a: LatLng, b: LatLng): Double { -// val ax = a.longitude -// val ay = a.latitude -// val bx = b.longitude -// val by = b.latitude -// val px = p.longitude -// val py = p.latitude -// -// val cross = (px - ax) * (bx - ax) + (py - ay) * (by - ay) -// if (cross <= 0.0) return distanceBetween(p, a) -// -// val len2 = (bx - ax).pow(2) + (by - ay).pow(2) -// if (cross >= len2) return distanceBetween(p, b) -// -// val t = cross / len2 -// val nearX = ax + t * (bx - ax) -// val nearY = ay + t * (by - ay) -// return distanceBetween(p, LatLng(nearY, nearX)) -// } -// -// /** -// * 相邻两点插值补点,让线条更顺滑 -// * @param step 插值个数 推荐2~3 -// */ -// private fun latLngInterpolate(points: List, step: Int = 2): List { -// if (points.size < 2) return points -// val result = mutableListOf() -// for (i in 0 until points.size - 1) { -// val p0 = points[i] -// val p1 = points[i + 1] -// result.add(p0) -// for (s in 1..step) { -// val ratio = s.toDouble() / (step + 1) -// val lat = p0.latitude + (p1.latitude - p0.latitude) * ratio -// val lng = p0.longitude + (p1.longitude - p0.longitude) * ratio -// result.add(LatLng(lat, lng)) -// } -// } -// result.add(points.last()) -// return result -// } -// -// /** -// * GPS降噪,过滤跳点漂移 -// */ -// private fun filterNoisePoint( -// points: List, minDis: Double = 5.0, maxDis: Double = 60.0 -// ): List { -// if (points.isEmpty()) return emptyList() -// val res = mutableListOf().apply { add(points.first()) } -// for (i in 1 until points.size) { -// val last = res.last() -// val dis = distanceBetween(last, points[i]) -// if (dis in minDis..maxDis) { -// res.add(points[i]) -// } -// } -// return res -// } } diff --git a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/EditWiFiZoneGoogleMapFragment.kt b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/EditWiFiZoneGoogleMapFragment.kt index e36e7c5..88fc378 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/EditWiFiZoneGoogleMapFragment.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/EditWiFiZoneGoogleMapFragment.kt @@ -1,22 +1,17 @@ package com.abbidot.tracker.ui.fragment.map.googlemap import android.content.Context -import androidx.fragment.app.viewModels import com.abbidot.tracker.bean.WiFiZoneBean -import com.abbidot.tracker.vm.GeoCoderViewModel import com.google.android.gms.maps.GoogleMap -import com.google.android.gms.maps.model.Marker /** *Created by .yzq on 2024/6/4/004. * @link - * @description: - */ -class EditWiFiZoneGoogleMapFragment( + * @description: 编辑WiFi区域地图 + * */ +class EditWiFiZoneGoogleMapFragment() : BaseGoogleMapFragment() { -) : BaseGoogleMapFragment() { - - private val mGeoCoderViewModel: GeoCoderViewModel by viewModels() +// private val mGeoCoderViewModel: GeoCoderViewModel by viewModels() private lateinit var mMapLoadOk: () -> Unit private lateinit var mWiFiZoneBean: WiFiZoneBean @@ -33,34 +28,33 @@ class EditWiFiZoneGoogleMapFragment( override fun onMapLoadOk(googleMap: GoogleMap) { - googleMap.setOnMarkerDragListener(object : GoogleMap.OnMarkerDragListener { - override fun onMarkerDrag(marker: Marker) { +// googleMap.setOnMarkerDragListener(object : GoogleMap.OnMarkerDragListener { +// override fun onMarkerDrag(marker: Marker) { +// +// } +// +// override fun onMarkerDragEnd(marker: Marker) { +// marker.position.let { +// mGeoCoderViewModel.getLatLonAddress(it.latitude, it.longitude, false) +// mWiFiZoneBean.latitude = it.latitude +// mWiFiZoneBean.longitude = it.longitude +// } +// } +// +// override fun onMarkerDragStart(marker: Marker) { +// +// } +// }) - } - - override fun onMarkerDragEnd(marker: Marker) { - marker.position.let { - mGeoCoderViewModel.getLatLonAddress(it.latitude, it.longitude, false) - mWiFiZoneBean.latitude = it.latitude - mWiFiZoneBean.longitude = it.longitude - } - } - - override fun onMarkerDragStart(marker: Marker) { - - } - }) - - getLastLocation() //变量是否初始化 if (::mMapLoadOk.isInitialized) mMapLoadOk() } - override fun liveDataObserve() { - mGeoCoderViewModel.mLatLonAddressLiveData.observe(viewLifecycleOwner) { - mWiFiZoneBean.address = it - } - } +// override fun liveDataObserve() { +// mGeoCoderViewModel.mLatLonAddressLiveData.observe(viewLifecycleOwner) { +// mWiFiZoneBean.address = it +// } +// } } \ No newline at end of file diff --git a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/FencesAddEditGoogleMapFragment.kt b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/FencesAddEditGoogleMapFragment.kt index 74c56ca..7a3e85f 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/FencesAddEditGoogleMapFragment.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/FencesAddEditGoogleMapFragment.kt @@ -100,7 +100,6 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() { } } - getLastLocation() //变量是否初始化 if (::mMapLoadOk.isInitialized) mMapLoadOk() @@ -197,13 +196,16 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() { val limitRadius = 100 / stepDistance * 50 //限制矩形边长100m val limitSide = 100 / stepDistance * 100 - LogUtil.e("setScaleLimitDistance,$stepDistance,$limitRadius,$limitSide,${cameraPosition.zoom}") + LogUtil.e("ScaleLimitDistance,$stepDistance,$limitRadius,$limitSide,${cameraPosition.zoom}") mFencesCircleView.mLimitRadius = limitRadius.toFloat() mFencesRectView.mLimitSide = limitSide.toFloat() mFencesPolygonView.mLimitSide = limitSide.toFloat() } } + /** + * 返回2种距离,第一个是设备使用真实距离,第二个是界面显示10的倍数距离 + */ private fun getLatLngAndCalDistance(): Array { if (null == mGoogleMap) return arrayOf("0", "0") @@ -227,7 +229,7 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() { endLatLng.longitude ) val distanceInt = distance.toInt() - val showDistance = getShowDistance(distanceInt) + val showDistance = Util.getShowDistance(distanceInt) LogUtil.e("getLatLngAndCalDistance,$distanceInt,$showDistance") mFencesBean.apply { toGpsLatLon(centreLatLng).let { @@ -276,9 +278,9 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() { rectCLatLng.longitude ) val widthDistance = rectWidthDistance.toInt() - val showWidthDistance = getShowDistance(widthDistance) + val showWidthDistance = Util.getShowDistance(widthDistance) val heightDistance = rectHeightDistance.toInt() - val showHeightDistance = getShowDistance(heightDistance) + val showHeightDistance = Util.getShowDistance(heightDistance) mFencesBean.apply { toGpsLatLon(centreLatLng).let { latitudeCenter = it.latitude @@ -374,16 +376,6 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() { } } - /** - * 获取ui显示的距离,经过算法处理的 - */ - private fun getShowDistance(distance: Int): Int { - val singleDigit = distance % 10 - val integerDigit = distance / 10 * 10 - return if (singleDigit > 4) integerDigit + 10 - else integerDigit - } - /** * 还原围栏 */ @@ -394,14 +386,14 @@ class FencesAddEditGoogleMapFragment : BaseGoogleMapFragment() { when (mFencesBean.fenceShapeType) { ConstantInt.CircleShapeType -> { restoreCircleFences() - val showDistance = getShowDistance(radius) + val showDistance = Util.getShowDistance(radius) arrayOfDistance = arrayOf("$radius", "$showDistance") } ConstantInt.RectangleShapeType -> { restoreRectFences() - val showWidthDistance = getShowDistance(longDistance) - val showHeightDistance = getShowDistance(shortDistance) + val showWidthDistance = Util.getShowDistance(longDistance) + val showHeightDistance = Util.getShowDistance(shortDistance) arrayOfDistance = arrayOf( "$longDistance", "$shortDistance", diff --git a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/HistoryDataGoogleMapFragment.kt b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/HistoryDataGoogleMapFragment.kt index bba5fe0..c614412 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/HistoryDataGoogleMapFragment.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/HistoryDataGoogleMapFragment.kt @@ -114,8 +114,6 @@ class HistoryDataGoogleMapFragment : BaseGoogleMapFragment() { } } - getLastLocation() - //变量是否初始化 if (::mMapLoadOk.isInitialized) mMapLoadOk() } diff --git a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/HomeMapGoogleMapFragmentV3.kt b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/HomeMapGoogleMapFragmentV3.kt index 30736d8..e2b5cb5 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/HomeMapGoogleMapFragmentV3.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/HomeMapGoogleMapFragmentV3.kt @@ -181,7 +181,6 @@ class HomeMapGoogleMapFragmentV3 : BaseGoogleMapFragment() { return false } }) - getLastLocation() } //变量是否初始化 diff --git a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/MarkerInfoWindowAdapter.kt b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/MarkerInfoWindowAdapter.kt index 8707878..10b2c32 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/MarkerInfoWindowAdapter.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/MarkerInfoWindowAdapter.kt @@ -60,12 +60,15 @@ class MarkerInfoWindowAdapter(context: Context) : GoogleMap.InfoWindowAdapter { LogUtil.d("$tag-----------") if (null == tag) return - if (TextUtils.isEmpty(tag.dayTime)) { - locationUpdateTextView.visibility = View.GONE - } else { - locationUpdateTextView.visibility = View.VISIBLE + locationUpdateTextView.visibility = if (TextUtils.isEmpty(tag.dayTime)) View.GONE + else { locationUpdateTextView.text = tag.dayTime + View.VISIBLE + } + locationTextView.visibility = if (TextUtils.isEmpty(tag.address)) View.GONE + else { + locationTextView.text = tag.address + View.VISIBLE } - locationTextView.text = tag.address } } \ No newline at end of file diff --git a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/PreviewFencesGoogleMapFragment.kt b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/PreviewFencesGoogleMapFragment.kt index 75dd1a4..ce485bf 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/PreviewFencesGoogleMapFragment.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/PreviewFencesGoogleMapFragment.kt @@ -23,7 +23,6 @@ class PreviewFencesGoogleMapFragment : BaseGoogleMapFragment() { } override fun onMapLoadOk(googleMap: GoogleMap) { - getLastLocation() //变量是否初始化 if (::mMapLoadOk.isInitialized) mMapLoadOk() } diff --git a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/WiFiZone2GoogleMapFragment.kt b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/WiFiZone2GoogleMapFragment.kt index 4bff829..de45ff1 100644 --- a/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/WiFiZone2GoogleMapFragment.kt +++ b/app/src/main/java/com/abbidot/tracker/ui/fragment/map/googlemap/WiFiZone2GoogleMapFragment.kt @@ -3,8 +3,11 @@ package com.abbidot.tracker.ui.fragment.map.googlemap import android.content.Context import android.location.Location import androidx.fragment.app.viewModels +import com.abbidot.baselibrary.constant.MMKVKey +import com.abbidot.baselibrary.util.MMKVUtil import com.abbidot.tracker.R import com.abbidot.tracker.bean.HistoryDataBean +import com.abbidot.tracker.util.LonAndLatUtil import com.abbidot.tracker.vm.GeoCoderViewModel import com.google.android.gms.maps.GoogleMap import com.google.android.gms.maps.model.LatLng @@ -20,11 +23,13 @@ class WiFiZone2GoogleMapFragment : BaseGoogleMapFragment() { //wifi zone当前位置信息 //保存地理信息,方便传参给其他页面 var mDecWifiAddressData: HistoryDataBean? = null + private var isFirstBind = false companion object { @JvmStatic - fun newInstance(context: Context) = WiFiZone2GoogleMapFragment().apply { + fun newInstance(context: Context, firstBind: Boolean) = WiFiZone2GoogleMapFragment().apply { mContext = context + isFirstBind = firstBind } } @@ -67,7 +72,6 @@ class WiFiZone2GoogleMapFragment : BaseGoogleMapFragment() { mMarker?.showInfoWindow() } } - getLastLocation() } override fun liveDataObserve() { @@ -106,6 +110,11 @@ class WiFiZone2GoogleMapFragment : BaseGoogleMapFragment() { override fun locationSuccess(location: Location?) { location?.apply { + //首次添加设备,需要判断是否超出中国边界 + if (isFirstBind) { + val isOutOfChina = LonAndLatUtil.isLocationOutOfChina(latitude, longitude) + MMKVUtil.putBoolean(MMKVKey.isGpsToGCJ02, !isOutOfChina) + } val latLng = LatLng(latitude, longitude) moveCameraLocation(latLng) if (null == mMarker) { diff --git a/app/src/main/java/com/abbidot/tracker/util/BaiduLocationManager.kt b/app/src/main/java/com/abbidot/tracker/util/BaiduLocationManager.kt new file mode 100644 index 0000000..c04b140 --- /dev/null +++ b/app/src/main/java/com/abbidot/tracker/util/BaiduLocationManager.kt @@ -0,0 +1,64 @@ +package com.abbidot.tracker.util + +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.ServiceConnection +import android.os.IBinder +import com.abbidot.tracker.service.BaiduLocationService +import com.easysocket.utils.LogUtil + +/** + * 百度定位管理器 + */ +object BaiduLocationManager { + + private var locationService: BaiduLocationService? = null + private var isServiceBound = false + + //服务连接回调 + private val serviceConnection = object : ServiceConnection { + override fun onServiceConnected(className: ComponentName, service: IBinder) { + val binder = service as BaiduLocationService.LocalBinder + locationService = binder.getService() + isServiceBound = true + } + + override fun onServiceDisconnected(arg0: ComponentName) { + isServiceBound = false + locationService = null + } + } + + // 初始化:绑定服务(建议在Application或首页初始化) + fun init(context: Context) { + if (!isServiceBound) { + Intent(context, BaiduLocationService::class.java).also { intent -> + context.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE) + } + } + } + + // 启动定位(所有页面统一调用此方法) + fun startLocation(locationPeriod: Int = 1, needStopLocation: Boolean = false) { + locationService?.startLocation(locationPeriod, needStopLocation) + } + + // 停止定位 + fun stopLocation() { + locationService?.stopLocation() + } + + // 释放资源(如退出应用时调用) + fun releaseServer(context: Context) { + try { + if (isServiceBound) { + LogUtil.e("onDestroy: 释放定位服务") + context.unbindService(serviceConnection) + isServiceBound = false + } + } catch (e: Exception) { + LogUtil.e("释放定位服务失败,releaseServer:${e.message}") + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/abbidot/tracker/util/BleReportManage.kt b/app/src/main/java/com/abbidot/tracker/util/BleReportManage.kt index f325f38..01f44ae 100644 --- a/app/src/main/java/com/abbidot/tracker/util/BleReportManage.kt +++ b/app/src/main/java/com/abbidot/tracker/util/BleReportManage.kt @@ -1,8 +1,10 @@ package com.abbidot.tracker.util import com.abbidot.baselibrary.constant.EventName +import com.abbidot.baselibrary.constant.MMKVKey import com.abbidot.baselibrary.eventbus.XEventBus import com.abbidot.baselibrary.util.LogUtil +import com.abbidot.baselibrary.util.MMKVUtil import com.abbidot.tracker.bean.BleReportDataBean import com.abbidot.tracker.bean.HistoryDataBean import com.abbidot.tracker.constant.ConstantInt @@ -86,10 +88,12 @@ class BleReportManage( //定位方式 add(4) add(1) - val lon = (LonAndLatUtil.currentUserGPSLon * 1000000).toLong() + val userGpsLat = MMKVUtil.getDouble(MMKVKey.UserGpsLat) + val userGpsLon = MMKVUtil.getDouble(MMKVKey.UserGpsLon) + val lon = (userGpsLat * 1000000).toLong() val lonByteArray = SRBleCmdUtil.instance.longTo4ByteArray(lon) addAll(lonByteArray.toMutableList()) - val lat = (LonAndLatUtil.currentUserGPSLat * 1000000).toLong() + val lat = (userGpsLon * 1000000).toLong() val latByteArray = SRBleCmdUtil.instance.longTo4ByteArray(lat) addAll(latByteArray.toMutableList()) addAll(timeStampByteArray.toMutableList()) diff --git a/app/src/main/java/com/abbidot/tracker/util/GoogleLocationManager.kt b/app/src/main/java/com/abbidot/tracker/util/GoogleLocationManager.kt new file mode 100644 index 0000000..901f43c --- /dev/null +++ b/app/src/main/java/com/abbidot/tracker/util/GoogleLocationManager.kt @@ -0,0 +1,64 @@ +package com.abbidot.tracker.util + +import android.content.ComponentName +import android.content.Context +import android.content.Intent +import android.content.ServiceConnection +import android.os.IBinder +import com.abbidot.tracker.service.GoogleLocationService +import com.easysocket.utils.LogUtil + +/** + * 谷歌定位管理器 + */ +object GoogleLocationManager { + + private var locationService: GoogleLocationService? = null + private var isServiceBound = false + + //服务连接回调 + private val serviceConnection = object : ServiceConnection { + override fun onServiceConnected(className: ComponentName, service: IBinder) { + val binder = service as GoogleLocationService.LocalBinder + locationService = binder.getService() + isServiceBound = true + } + + override fun onServiceDisconnected(arg0: ComponentName) { + isServiceBound = false + locationService = null + } + } + + // 初始化:绑定服务(建议在Application或首页初始化) + fun init(context: Context) { + if (!isServiceBound) { + Intent(context, GoogleLocationService::class.java).also { intent -> + context.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE) + } + } + } + + // 启动定位(所有页面统一调用此方法) + fun startLocation() { + locationService?.startLocation() + } + + // 停止定位 + fun stopLocation() { + locationService?.stopLocation() + } + + // 释放资源(如退出应用时调用) + fun releaseServer(context: Context) { + try { + if (isServiceBound) { + LogUtil.e("onDestroy: 释放定位服务") + context.unbindService(serviceConnection) + isServiceBound = false + } + } catch (e: Exception) { + LogUtil.e("释放定位服务失败,releaseServer:${e.message}") + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/abbidot/tracker/util/GoogleLocationUtil.java b/app/src/main/java/com/abbidot/tracker/util/GoogleLocationUtil.java deleted file mode 100644 index 2219969..0000000 --- a/app/src/main/java/com/abbidot/tracker/util/GoogleLocationUtil.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.abbidot.tracker.util; - -import android.annotation.SuppressLint; -import android.app.Activity; -import android.content.Context; -import android.os.Looper; - -import androidx.annotation.NonNull; - -import com.abbidot.baselibrary.util.LogUtil; -import com.google.android.gms.location.FusedLocationProviderClient; -import com.google.android.gms.location.LocationCallback; -import com.google.android.gms.location.LocationRequest; -import com.google.android.gms.location.LocationResult; -import com.google.android.gms.location.LocationServices; - -/** - * Created by .yzq on 2023/10/18/018. - * - * @link - * @description: 谷歌定位,暂未使用 - */ -public class GoogleLocationUtil { - private LocationRequest mLocationRequest; - - @SuppressLint("MissingPermission") - public GoogleLocationUtil(Context context) { - createLocationRequest(); - - FusedLocationProviderClient fusedLocationClient = - LocationServices.getFusedLocationProviderClient(context); - - LogUtil.Companion.e("GoogleLocationUtil"); - - // LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder(); - // - // builder.addLocationRequest(mLocationRequest); - - fusedLocationClient.requestLocationUpdates(mLocationRequest, new LocationCallback() { - @Override - public void onLocationResult(@NonNull LocationResult locationResult) { - super.onLocationResult(locationResult); - LogUtil.Companion.e("onLocationResult" + locationResult.getLastLocation()); - } - }, Looper.myLooper()); - - fusedLocationClient.getLastLocation().addOnSuccessListener((Activity) context, location -> { - if (location != null) { - // Logic to handle location object - LogUtil.Companion.e("addOnSuccessListener" + location.getLatitude()); - } else { - // Handle null case or Request periodic location update https://developer.android.com/training/location/receive-location-updates - LogUtil.Companion.e("addOnSuccessListener,location == null"); - } - }); - - } - - - private void createLocationRequest() { - mLocationRequest = LocationRequest.create(); - //更新间隔 - mLocationRequest.setInterval(2000); - mLocationRequest.setFastestInterval(1000); - mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); - } - -} diff --git a/app/src/main/java/com/abbidot/tracker/util/ImageUtil.kt b/app/src/main/java/com/abbidot/tracker/util/ImageUtil.kt index ae83d1d..029c4a6 100644 --- a/app/src/main/java/com/abbidot/tracker/util/ImageUtil.kt +++ b/app/src/main/java/com/abbidot/tracker/util/ImageUtil.kt @@ -232,9 +232,7 @@ object ImageUtil { */ fun getBitmapFromDrawableAndSvg(context: Context, @DrawableRes drawableId: Int): Bitmap? { return when (val drawable = ContextCompat.getDrawable(context, drawableId)) { - is BitmapDrawable -> { - drawable.bitmap - } + is BitmapDrawable -> drawable.bitmap is VectorDrawable, is VectorDrawableCompat -> { val bitmap = Bitmap.createBitmap( diff --git a/app/src/main/java/com/abbidot/tracker/util/LonAndLatUtil.kt b/app/src/main/java/com/abbidot/tracker/util/LonAndLatUtil.kt index fddc2fd..ff1ce8b 100644 --- a/app/src/main/java/com/abbidot/tracker/util/LonAndLatUtil.kt +++ b/app/src/main/java/com/abbidot/tracker/util/LonAndLatUtil.kt @@ -16,10 +16,6 @@ class LonAndLatUtil { companion object { - //当前用户的GPS经纬度 - var currentUserGPSLat = 0.0 - var currentUserGPSLon = 0.0 - private const val a = 6378245.0 private const val ee = 0.00669342162296594323 diff --git a/app/src/main/java/com/abbidot/tracker/util/Util.kt b/app/src/main/java/com/abbidot/tracker/util/Util.kt index 595432b..5641ff2 100644 --- a/app/src/main/java/com/abbidot/tracker/util/Util.kt +++ b/app/src/main/java/com/abbidot/tracker/util/Util.kt @@ -96,6 +96,16 @@ class Util { return Utils.formatDecimal(dis).toDouble() } + /** + * 获取地图ui显示的距离,以10的倍数显示 + */ + fun getShowDistance(distance: Int): Int { + val singleDigit = distance % 10 + val integerDigit = distance / 10 * 10 + return if (singleDigit > 4) integerDigit + 10 + else integerDigit + } + /** * 转换英制单位 * @param type 0=in 1=lbs 2=mph 3=ft diff --git a/app/src/main/java/com/abbidot/tracker/vm/DeviceDFUViewModel.kt b/app/src/main/java/com/abbidot/tracker/vm/DeviceDFUViewModel.kt index 9355de1..cdd0b30 100644 --- a/app/src/main/java/com/abbidot/tracker/vm/DeviceDFUViewModel.kt +++ b/app/src/main/java/com/abbidot/tracker/vm/DeviceDFUViewModel.kt @@ -89,6 +89,8 @@ class DeviceDFUViewModel(application: Application) : AndroidViewModel(applicatio newVersion = true break } + //只要有一位本地版本号大于服务版本号,就认为是新版本号,无需更新 + else if (serviceVersions[i].toInt() < localVersions[i].toInt()) break } return newVersion } catch (e: Exception) { diff --git a/app/src/main/java/com/abbidot/tracker/vm/FencesMapViewModel.kt b/app/src/main/java/com/abbidot/tracker/vm/FencesMapViewModel.kt index 6dbc8f9..17eb8f9 100644 --- a/app/src/main/java/com/abbidot/tracker/vm/FencesMapViewModel.kt +++ b/app/src/main/java/com/abbidot/tracker/vm/FencesMapViewModel.kt @@ -10,6 +10,7 @@ import com.abbidot.tracker.constant.ConstantInt import com.abbidot.tracker.ui.fragment.map.baidumap.BaseBaiduMapFragment import com.abbidot.tracker.ui.fragment.map.googlemap.BaseGoogleMapFragment import com.google.android.gms.maps.model.LatLng +import kotlin.math.abs /** *Created by .yzq on 2022/3/2/002. @@ -121,7 +122,7 @@ class FencesMapViewModel : ViewModel() { } if (null == fencesList) return - if (fencesList.size == 0) return + if (fencesList.isEmpty()) return val saveFillColor = ContextCompat.getColor(context, R.color.select_color4) var saveStrokeColor = ContextCompat.getColor(context, R.color.select_color) @@ -190,10 +191,24 @@ class FencesMapViewModel : ViewModel() { } } else if (mapFragment is BaseBaiduMapFragment) { if (it.fenceShapeType == ConstantInt.CircleShapeType) { + var mapRadius = it.radius + mapFragment.mBaiduMap?.let { map -> + val pointCentre = map.projection.toScreenLocation( + mapFragment.getBaiduMapLatLng( + it.latitudeCenter, it.longitudeCenter + ) + ) + val pointLineEnd = map.projection.toScreenLocation( + mapFragment.getBaiduMapLatLng( + it.ancillaryLatitude, it.ancillaryLongitude + ) + ) + mapRadius = abs(pointLineEnd.x - pointCentre.x) + } mapFragment.addCircleDashedAndImageFence( it.latitudeCenter, it.longitudeCenter, - it.radius.toDouble(), + mapRadius.toDouble(), imageTypeResId, strokeColor, fillColor diff --git a/app/src/main/java/com/abbidot/tracker/vm/GoogleLocationViewModel.kt b/app/src/main/java/com/abbidot/tracker/vm/GoogleLocationViewModel.kt index 0a20de3..4cd2c8d 100644 --- a/app/src/main/java/com/abbidot/tracker/vm/GoogleLocationViewModel.kt +++ b/app/src/main/java/com/abbidot/tracker/vm/GoogleLocationViewModel.kt @@ -8,7 +8,6 @@ import androidx.lifecycle.ViewModel import com.abbidot.baselibrary.constant.MMKVKey import com.abbidot.baselibrary.util.LogUtil import com.abbidot.baselibrary.util.MMKVUtil -import com.abbidot.tracker.util.LonAndLatUtil import com.google.android.gms.location.FusedLocationProviderClient import com.google.android.gms.location.LocationServices import com.google.android.gms.location.Priority @@ -99,8 +98,6 @@ class GoogleLocationViewModel : ViewModel() { MMKVUtil.putDouble(MMKVKey.UserGpsLon, longitude) //单位是米/秒(m/s) MMKVUtil.putFloat(MMKVKey.UserGpsSpeed, speed) - LonAndLatUtil.currentUserGPSLat = location.latitude - LonAndLatUtil.currentUserGPSLon = location.longitude } } diff --git a/app/src/main/res/layout/activity_help_tracker_status.xml b/app/src/main/res/layout/activity_help_tracker_status.xml index 7d060ea..581cd0a 100644 --- a/app/src/main/res/layout/activity_help_tracker_status.xml +++ b/app/src/main/res/layout/activity_help_tracker_status.xml @@ -64,7 +64,7 @@ android:gravity="start" android:text="@string/txt_help_status_network" android:textSize="@dimen/textSize16" - app:lineHeight="@dimen/textSize18" /> + app:lineHeight="@dimen/textSize22" /> - - - - - - - - - - - - - - + app:lineHeight="@dimen/textSize22" /> + android:layout_marginTop="@dimen/dp_16" /> - Keine E-Mail erhalten? Messen Sie vom Boden bis zum höchsten Punkt der \nSchulterblätter Ihres Haustiers. Batterie: %s%% %s Jahre - %d Jahr %d lb - %d/100 Verdient - Letzte Aktualisierung: %s - Track & Punkte anzeigen - Möchten Sie die Daten des Haustiers wirklich mit \' %s \' teilen? - Bitte wählen Sie 2 bis 9 Fotos aus. - Verlängerung zu %.2f/Jahr danach & jederzeit kündbar - $%d Rabatt erhalten - %d Jahre Verbindungsabonnement - Das Abonnement ist bis zum %s aktiv. - Die automatische Verlängerung ist deaktiviert. Das Abonnement endet am %s. - Speichern & Bestätigen Version%s Allgemeine Geschäftsbedingungen Datenschutzrichtlinie & Nutzungsbedingungen akzeptieren Der Tracker ist mit %s gekoppelt. Aktivitätsziel Endzeit - $%s/Monat Gestalten Sie den Tagesablauf Ihres Haustiers mit \ngezielten Aktivitäten am Morgen und Abend individuell und \nabwechslungsreich – abgestimmt auf seine Bedürfnisse, \nArt und Rasse. +\tEinladen Ihr freigegebenes Familienmitglied oder Ihr Freund kann \nden Standort und die Daten Ihres Haustiers verfolgen, \nohne diese bearbeiten zu können. - Sie haben Ihr Haustier erfolgreich eingerichtet und \ndas Sicherheits-Abzeichen erhalten! Bitte geben Sie den 4-stelligen Code ein, der an %s gesendet wurde. Verbleibende Zeit:\t Mit der Registrierung akzeptieren Sie die Allgemeinen Geschäftsbedingungen und die Bestätigen Sie, dass die 6-stellige ID mit der auf \nder Rückseite des Trackers übereinstimmt. Suchen Sie die 6-stellige ID auf der Rückseite \ndes Trackers. Die Tracker-ID ist ungültig. Bitte überprüfen Sie \ndie Eingabe und versuchen Sie es erneut. - Das Gerät ist bereits verknüpft. Bitte überprüfen Sie \ndie Eingabe und versuchen Sie es erneut. Erfolgreich \ngekoppelt - Ablaufdatum (Verlängert sich für Ist dies das Zuhause Ihres Haustiers? - %sft - %smph Zuweisung aufheben %s - Möchten Sie die Familie %s wirklich löschen? •\tErforderlich für eine präzise Synchronisierung der Aktivitätsdaten. •\tIhren eigenen Standort auf der Karte anzeigen•\t Erforderlich zur Synchronisierung von Aktivitätsdaten•\t Verbessert die Genauigkeit des Trackers •\tBenachrichtigungen aktivieren, um wichtige Informationen zu erhalten, z. B. wenn Ihr Haustier eine Sicherheitszone verlassen hat oder der Akku Ihres Geräts geladen werden sollte. @@ -51,14 +31,11 @@ Wählen Sie „Haustier“ > „Tracker“. Klicken Sie auf „GPS-Update“ und wählen Sie 3/5/10/15 Minuten. (Kürzere Netzwerkintervalle entladen den Akku des Trackers schneller. Standardmäßig verbindet sich das Gerät alle 15 Minuten erneut mit dem Netzwerk.) Wenn der Live-Modus aktiviert ist, wechselt der Tracker in einen schnellen Positions- und Netzwerkmodus, normalerweise innerhalb von 15–20 Sekunden. Dieser Modus verbraucht den Akku am schnellsten und sollte daher nur in Notfällen verwendet werden. - Benachrichtigungen aktivieren: Gehen Sie zu „Konto“ > „Einstellungen“. Klicken Sie auf „Benachrichtigungen“ und aktivieren Sie sie. Verlängerung: - Monat x%s - /%s Jahr Wir senden den Bestätigungscode an %s. Upgrade auf Prime, \num exklusive Funktionen freizuschalten! Neue Firmware-Version erkannt: %s - „%s“ lädt Sie ein, bei „%s“ einzuchecken + “%s” lädt Sie ein, bei “%s” einzuchecken Ihr Abonnement ist abgelaufen,\nbitte aufladen %s Zäune eingerichtet %s ist in der Nähe @@ -72,83 +49,22 @@ Bewegen Sie %s, um es aufzuwecken (vor %s) Ersteinrichtung kann %s Minuten dauern - 1. Bringen Sie das Gerät nach draußen -\n2. Warten Sie auf die LTE- und GPS-Verbindung -\n3. Blaues Blinken = LTE & GPS aktiv - 1. Bringen Sie das Gerät nach draußen -\n2. Warten Sie auf die LTE- und GPS-Verbindung -\n3. Grünes Blinken = LTE & GPS aktiv - 1.Flexible Kurzzeitabsicherung -\n2.Standard-Kundensupport - 1. 1 Geräteaustausch inklusive -\n2. Dedizierter Kundensupport -\n3. Jährlicher Schutzumfang - 1. VIP-Prioritäts-Support -\n2. Schneller Ersatzservice (1 inklusive) -\n3. Erweiterter Schutz -\n4. Sorgenfreie Haustierabsicherung + 1. Bringen Sie das Gerät nach draußen\n\n2. Warten Sie auf die LTE- und GPS-Verbindung\n\n3. Blaues Blinken = LTE & GPS aktiv + 1. Bringen Sie das Gerät nach draußen\n\n2. Warten Sie auf die LTE- und GPS-Verbindung\n\n3. Grünes Blinken = LTE & GPS aktiv + 1.Flexible Kurzzeitabsicherung\n\n2.Standard-Kundensupport + 1. 1 Geräteaustausch inklusive\n\n2. Dedizierter Kundensupport\n\n3. Jährlicher Schutzumfang + 1. VIP-Prioritäts-Support\n\n2. Schneller Ersatzservice (1 inklusive)\n\n3. Erweiterter Schutz\n\n4. Sorgenfreie Haustierabsicherung %s Min - Stand: %s %s Min. - Willkommen bei der Abbidot-App! Zum besseren Schutz Ihrer Rechte erläutern wir Ihnen in dieser Datenschutzerklärung, wie wir die von Ihnen bereitgestellten Informationen erfassen, verwenden, verarbeiten und schützen. Bitte lesen Sie die Datenschutzrichtlinie und die Nutzungsbedingungen sorgfältig durch. Ja - %d Tracker - %d Haustiere - %d Zoll - Berechtigung konnte nicht abgerufen werden. - Keine Haustiere - Bitte verknüpfen Sie zuerst ein Haustier. - %d%% - %dY %dMo - Alle Videos - Abgeschlossen(%1$d/%2$d) - Es werden bis zu %d Fotos oder Videos unterstützt. - Es werden bis zu %d Fotos unterstützt. - Es werden bis zu %d Videos unterstützt. - The width of the photo should be greater than %1$d and the height should be greater than %1$d - Bitte gewähren Sie die entsprechenden Berechtigungen - Bitte gewähren Sie die entsprechenden Berechtigungen - %1$d/%2$d - Heute\t%s - Video auswählen - $\t%.2f - %s%% - Geben Sie die für Ihr Profil registrierte E-Mail-Adresse ein. \nWir senden einen 4-stelligen Bestätigungscode an Ihre \nE-Mail-Adresse. - $%s - $%s/Monat - $%s/Jahr - Dadurch werden alle Daten von %s dauerhaft aus Ihrem Konto gelöscht. - (Verlängert sich für $%s pro Jahr) - Aktivierung \nerfolgreich - Starte %s-minütiges LIVE - Code gültig für %ss - Ihr Freund %s lädt Sie ein, %s-Familienmitglied zu werden. - Verlängerung: $%s/year on %s - Verlängerung: $%s/month on %s - Jährlicher Geräteschutz - (Verlängerung zu $%s jährlich danach) - (Verlängerung danach für $%s pro Monat) - Fehler - Zahlungsmethode bearbeiten - Kein Signal. Prüfen Sie, ob sich das Haustier im Innenbereich befindet. Kartennummer existiert bereits. Überschreiben? - Bitte Passwort eingeben. - Bitte E-Mail-Adresse eingeben. WLAN sorgt dafür, dass Ihr Tracker verbunden bleibt, wenn LTE-Signale schwach sind. Verlängerung: $%s/%s Tag am %s /Tag x%s - Die ABBIDOT App sammelt Standortdaten. Die Route und die Entfernung zwischen dem aktuellen Standort und dem Gerät können berechnet werden. - (Verlängerung danach für $%s pro Tag) - (Verlängerung danach für $%s/%s Tage) - (Verlängerung danach für $%s/%s Jahre) - (Verlängerung danach für $%s/%s Monate) %s-Jahrespflege - Ablaufzeit: 1 Ersatzgerät/Jahr, egal aus welchem Grund Bluetooth-Radar Gespeichert. Aktiv, wenn online. - Verlängerung: $%s/%s Jahre am %s - Verlängerung: $%s/%s Monate am %s Rückerstattungsfrist ist abgelaufen Rückerstattungsrichtlinie\n Automatische Rückerstattung (innerhalb von 48 Stunden) @@ -157,329 +73,140 @@ Nach den ersten 48 Stunden können Nutzer innerhalb von 30 Tagen nach Kauf eine Rückerstattung beantragen.\n\t1. Alle Abonnementpläne (3 Monate, 1 Jahr, 2 Jahre) sind berechtigt\n\t2. Rückerstattungsanträge unterliegen einer Prüfung und Genehmigung\n\t3. Rückerstattungen können je nach Nutzung und Serviceverbrauch teilweise angepasst werden\n Abonnements, die älter als 30 Tage sind, sind nicht erstattungsfähig. Keine Rückerstattung nach 30 Tagen + Garten + Park + Spielen + Unsicher + Gemüsegarten + Wasser Willkommen zurück E-Mail - Telefonnummer Passwort Passwort vergessen? - Mit WeChat anmelden - Mit Bestätigungscode anmelden - Mit Apple anmelden - Mit Konto anmelden - Neues Passwort festlegen - Bestätigungscode gesendet Noch kein Konto? - Mit Passwort anmelden Registrieren - Hey, Zurück zur Anmeldung - Anmeldepasswort festlegen Vollständiger Name - Code anfordern - Wir haben den Bestätigungscode an deine E-Mail-Adresse gesendet - Bestätigungscode Weiter Erneut senden Mit Zustimmung fortfahren. - Bitte lesen und akzeptieren Sie die - Nutzungsbedingungen - und die - Datenschutzrichtlinie Senden - Verknüpfen - Abgeschlossen - Daten Karte Profil - Meine Bestellungen - Hilfe-Center - Feedback Einstellungen - Einstellung Benachrichtigungen - Sprache Konto Über Cache leeren - Abmelden Feedback Art der Anfrage (erforderlich) - Zur App - Zum Tracker + Über + Gerät Sonstiges Bitte beschreiben Sie Ihr Problem oder Ihren Vorschlag - Bitte wählen Sie eine Anfragenart aus Bitte hinterlassen Sie Ihre E-Mail-Adresse, damit wir Ihnen schneller helfen können. Bild hochladen Name - Geschlecht Geburtsdatum - Standort E-Mail - Telefonnummer - Rasse Gewicht Größe So messen Sie die Größe Speichern Tags - Tracker-ID eingeben Aktivieren - Aktivieren Sie das Gerät, um fortzufahren. Nein, danke - Aktivieren Mein Tracker - Tracker - Mein Tracker - Autorisiert LED-Licht - Zaun - Einstellungen Neues Haustier Verknüpfung aufheben Netzwerk GPS - Tage Bluetooth verbunden Bluetooth nicht verbunden - LED-Licht - Aus - Ein - Zaun - Familie - Familienmitglied hinzufügen - Laden Sie Familienmitglieder ein, den Standort oder die Aktivitäten Ihres Haustiers zu teilen. Familienmitglieder können keine Zäune erstellen oder Einstellungen ändern. + AUS + AN Einladen Erfolgreich gesendet - Zurück GPS-Aktualisierungen - Ausschalten - Zäune - Zaundetails Name Form Zaun aktivieren - Radius Fertig - Dauerlicht Dauerhaft Atmungsmodus - Langsames Blinken Blinken Mein Haustier - Haustiere - Meine Haustiere - Autorisiert Männlich Weiblich - Über Bearbeiten - Aktivitätsabzeichen - Alle - Alle abbrechen - Niedriger Batteriestand - Live-Tracking beenden - Live-Tracking aktualisiert den Standort in Echtzeit, verbraucht jedoch mehr Akku. - Karte auswählen - Google Maps - Gaode Maps + Stoppen Abbrechen - Die App ist nicht installiert. Bitte laden Sie die App zuerst herunter und installieren Sie sie. Aktive Zeit - Ziel - Distanz Kalorien - Tracking-Zeit - Schlafzeit - Aktive Zeit - Verlauf - Aktivitätsdetails Ziel festlegen Ändern Aktuell - Track - Punkt Min. - Sek. Meile kcal - Tage Bitte füllen Sie alle Felder aus. - Das E-Mail-Format ist ungültig. Erfolgreich Erfolgreich hochgeladen - Erfolgreich hinzugefügt Erfolgreich gespeichert Erfolgreich angemeldet Erfolgreich geändert Hinweis Zaun hinzufügen - Zaun bearbeiten - Passwort vergessen? Keine Daten - Erfolgreich gelöscht Möchten Sie dies wirklich löschen? - Möchten Sie die Geräteverknüpfung wirklich aufheben? - Verknüpfung erfolgreich aufgehoben - Erfolgreich verknüpft - Das Gewicht muss größer als 0 sein. Heute Min. - Sek. - Meilen - kcal Tage - Ihr Gerät ist abgelaufen. Bitte verlängern Sie es. Live-Tracking beenden? Löschen Abbrechen - J Mo Ja Benachrichtigungen - Alle auswählen - Alle abwählen Anfrage fehlgeschlagen. Bitte versuchen Sie es erneut. - Karte wird geladen … - Registrierung erfolgreich - Hallo, leeres Fragment Alle Fotos - Fotos und Videos - Auswählen - Vorschau - Es kann nur ein Dateityp ausgewählt werden. - Kamera konnte nicht gestartet werden. - Ungültiges Bild. Bitte erteilen Sie die erforderlichen Berechtigungen. - Dieses Bildformat wird nicht unterstützt Bearbeiten - Löschen - Keine passenden Fotos - Keine passenden Videos - Original - Fertig - Abbrechen - Vorlage - Text - Datum - Doppeltippen zum Bearbeiten - Anpassen - Foto auswählen - GIF - Tage Automatische Verlängerung: - Aufladeverlauf Aufladen - Aufladebetrag - Bestelldetails - Zwischensumme - Gutschein - Aktionscode - Punkte Gesamtbetrag - Bezahlen - Zahlungsmethode auswählen - Neue Karte hinzufügen - Bestätigen - Zahlung - Zahlung erfolgreich - Zahlung fehlgeschlagen. Bitte versuchen Sie es erneut. Erneut versuchen Zurück - Abonnementplan: - Zahlungsintervall: - Ablaufdatum: - Englisch Möchten Sie sich wirklich abmelden? App-Cache wirklich löschen? Heller Modus - Firmware-Update - Erfolgreich übermittelt - Erfolgreich gelöscht Wird geladen … - Anmeldung fehlgeschlagen. Bitte versuchen Sie es erneut. Automatische Verlängerung kündigen? Bestätigen? - Automatische Verlängerung erfolgreich gekündigt. Die automatische Verlängerung ist bequem, da Sie sich keine Sorgen um ein Ablaufdatum machen müssen. Kartennummer - Name des Karteninhabers - KARTENINHABER - ABLAUFDATUM MM/JJ CVV - Bitte wählen Sie eine Zahlungsmethode aus. - Benutzer hat die Zahlung abgebrochen. Zahlung erfolgreich Zahlung fehlgeschlagen. Bitte versuchen Sie es erneut. - Ungültiges Ablaufdatum - Ungültiges Kreditkartenformat - Möchten Sie das Gerät wirklich ausschalten? - Zuschneiden Verbindung mit Bluetooth wird hergestellt - Konto löschen Durch das Löschen Ihres Kontos werden alle Daten dauerhaft entfernt. Möchten Sie fortfahren? - Konto erfolgreich gelöscht - Zum Beenden der App erneut drücken Falscher Benutzername oder falsches Passwort Falscher Bestätigungscode Bestätigungscode abgelaufen - Registrierung fehlgeschlagen Benutzer existiert nicht Benutzer existiert bereits - Ungültiges E-Mail-Format - Geräteverbindung trennen? - Verbindung erfolgreich - Verbindung fehlgeschlagen - Aktivierung erfolgreich - Aktivierung fehlgeschlagen. Bitte versuchen Sie es erneut. - Erstanmeldung - Bitte verknüpfen Sie Ihre Mobiltelefonnummer. - Bitte geben Sie Ihre Mobiltelefonnummer ein. Passwort zurücksetzen - Bestellung abschicken - $ - Verbleibende Nutzungstage - Gültigkeitsdauer - Tage - Gerät - Erneut aktivieren - Gesamtbetrag - Abbidot Datenschutzrichtlinie Website - Passwort zurücksetzen - Zahlung abbrechen Bitte aktivieren Sie Bluetooth auf Ihrem Smartphone. Sie können nicht mit sich selbst teilen. - Der aktuelle Benutzer hat dieses Gerät bereits verknüpft. - Vorname - Nachname Online Offline - Rechtliche Hinweise - Ich akzeptiere - Ablehnen - Keine Download-Adresse verfügbar - Möchten Sie die Firmware herunterladen und aktualisieren? - Bitte warten … - Versionsbeschreibung - Firmware-Name Firmware-Version - Firmware-Dateigröße Aktualisieren - Aktualisierung erfolgreich - Aktualisierung fehlgeschlagen - Firmware herunterladen - DFU-Modus wird aktiviert - Suche nach DFU-Geräten Gerät nicht gefunden - Verbindung zu Geräten wird hergestellt - Gerät erneut verbinden - Geräteverbindung getrennt Getrennt - Aktualisierung läuft - Upgrade wird vorbereitet - Gerät erfolgreich verbunden Bereits die neueste Version installiert Aktivität Route @@ -488,36 +215,27 @@ km Schlaf Live - Zone Tracker Abzeichen Alle anzeigen Verwalten Zeit - Startzeit - Virtuelle Zäune WLAN-Zone Verbunden Schwaches Signal - Batterie Bluetooth Licht - Von - Bis Track und Punkte anzeigen Alle lesen Abonnement Hilfe So funktioniert es - FAQ Einheiteneinstellungen - Shop Abmelden - Durchschnittlicher Kalorienverbrauch - Durchschnittliche Zeit + Ø Kalorien + Durchschnittszeit Gesamtdaten Std. - Gesamtdistanz Letzte 7 Tage Letzte 30 Tage OK @@ -533,21 +251,7 @@ Oktober November Dezember - Jan - Feb - Mär - Apr - Mai - Jun - Jul - Aug - Sep - Okt - Nov - Dez - Richtung Je schneller der Ton wird, desto näher ist die Entfernung. - Geschwindigkeit Radar stoppen WLAN-Zone bearbeiten WLAN-Name: @@ -562,12 +266,9 @@ Sperrzone hinzufügen Sperrzone bearbeiten Datenübersicht - Minimum - Empfohlen Std. Tagesziel festlegen Super! Bereit loszulegen! - Gesamte Aktivitätsdistanz km Durchschnittliche tägliche Aktivitätszeit Durchschnittlicher Kalorienverbrauch @@ -585,22 +286,16 @@ Mitglieder Aktiv Ausstehend - Beziehung Avatar auswählen - Freund - Partner Neue Meilensteine freischalten! - Kollege Herzlichen Glückwunsch! Teilen Anmelden Registrieren Konto erstellen - Datenschutzrichtlinie. Mindestens 6 Zeichen Land E-Mail-Adresse - Willkommen zurück Weiter OTP-Verifizierung Sek. @@ -609,19 +304,15 @@ Jetzt zurücksetzen Passwort bestätigen Passwort erfolgreich zurückgesetzt! - Zurücksetzen Standard Satellit Zäune anzeigen - Eingabe Auswählen Immer an Ihrer Seite! Unterstützt von Weniger anzeigen Alle anzeigen Abenteuer - Gesellig - Sportlich Neuer Tracker Neuen Tracker hinzufügen Aufladen und einschalten @@ -641,19 +332,15 @@ Monatliches Abonnement /Monat /Jahr - Bestes Preis-Leistungs-Verhältnis + Bestpreis Tarif bestätigen Gerätenummer Allgemeine Geschäftsbedingungen - Automatische Verlängerung - Über die automatische Verlängerung - Ihr Jahresabonnement wird am Ende jedes Abonnementzeitraums automatisch verlängert, damit der Service ohne Unterbrechung weiterläuft. Zusammenfassung Steuer - Gesamtbetrag inkl. Steuern Zahlungsmethode - Meine Karte - Keine Karte gefunden + Meine Karte + Keine Zahlungsmethode Neue Karte hinzufügen Primär Zahlung durchführen @@ -661,19 +348,14 @@ Zahlungsmethode hinzufügen Neue Karte speichern Zahlung erfolgreich abgeschlossen. - MM/JJ - CVC Akzeptierte Zahlungskarten Als Standardkarte festlegen Name auf der Karte Berechtigungen Überspringen - Aktivieren Erteilen Sie Berechtigungen für ein besseres Nutzungserlebnis. - Abonnementdetails Tracker-ID Tarif: - pro Jahr) Verlängerung am: Das Hinzufügen des Wohnorts kann die Akkulaufzeit verbessern und zusätzliche Sicherheit bieten. WLAN-Zone einrichten @@ -681,26 +363,19 @@ Fester Wohnort WLAN-Netzwerk auswählen Später - Welche Maßeinheiten möchten Sie für Ihr Haustier verwenden? - Größe Ihres Haustiers - Länge - Gewicht Ihres Haustiers Benachrichtigungseinstellungen - Betreten oder Verlassen der Sicherheitszone/Sperrzone + Sicherheits-/Sperrzone betreten/verlassen Tracker-Status - Abonnement-/Batteriewarnungen/Ausschalten + Abo / Akku schwach / Aus Aktivitäts-, Schlaf- und Zielerinnerungen - WLAN-Zone Über die WLAN-Zone Wählen Sie ein Netzwerk an einem vertrauenswürdigen Ort, an dem sich Ihr Haustier häufig aufhält, z. B. bei Ihnen zu Hause. Sobald sich der Tracker in Reichweite befindet, erkennt er dieses Netzwerk als WLAN-Zone. Büro - Sobald der Tracker erkennt, dass sich Ihr Haustier sicher in einer WLAN-Zone befindet, werden Live-Tracking, Licht und Ton deaktiviert, um die Akkulaufzeit zu verlängern. Akku sparen Innerhalb der Bluetooth-Reichweite? Finden Sie einen Tracker in der Nähe mit dem Radar. Live-Tracking wird ebenfalls verfügbar, verbraucht jedoch mehr Akku und beendet den Energiesparmodus. Verfolgen Sie Ihr Haustier - WLAN-Zonen-Einstellungen + WLAN-Zone Bitte geben Sie Ihr Feedback ein. - Bitte hinterlassen Sie Ihre E-Mail-Adresse, damit wir Ihnen schneller helfen können. Geben Sie Ihre E-Mail-Adresse ein Datei auswählen Ausschalten @@ -709,7 +384,6 @@ Aktuelle LED Sicherheitszone verlassen In der WLAN-Zone - WLAN-Zone verlassen In der Sperrzone Starkes Signal WLAN-Zone @@ -718,36 +392,25 @@ Bitte geben Sie Ihren vollständigen Namen ein. Bitte verwenden Sie ein gültiges Passwort. Bitte wählen Sie eine Region aus. - Zu ABBIDOT + bei ABBIDOT Die eingegebenen Passwörter stimmen nicht überein! Noch keine Mitglieder - Einladen Mitglieder einladen - Dadurch werden alle Daten von - dauerhaft aus Ihrem Konto gelöscht. Startseite Live-Dauer Über die Live-Dauer Der Live-Modus hilft dabei, Haustiere mit Standortaktualisierungen alle 2–3 Sekunden zu finden, verbraucht jedoch mehr Akku. Mit dem Standard-Tracking erhalten Sie weiterhin regelmäßige Standortaktualisierungen. Das Live-Tracking wird nach Ablauf der festgelegten Dauer automatisch beendet. Sie können es auch früher stoppen, um Akku zu sparen. Kurz halten - Bluetooth GPS-Standort Benachrichtigungen erhalten Einschalten Gerät nicht aktiviert. Bitte abonnieren, um es zu aktivieren. - Stunden - Suche … Lassen Sie den Tracker eingeschaltet und in der Nähe, um zu scannen. Draußen Drinnen - 7-Tage-Durchschnitt - Automatische Verlängerung stoppen - Automatische Verlängerung Sie haben zu viele Zäune erstellt. LIVE ist beendet. Die LIVE-Zeit kann in der Live-Dauer eingestellt werden. - Schwaches GPS-Signal - Kein Netzwerksignal Tracker ausgeschaltet LIVE wird gestartet … Verbindung zum Netzwerk wird hergestellt @@ -760,14 +423,11 @@ Live-Tracking wird nach einer Stunde beendet, Sie können es jedoch vorher stoppen, um Akku zu sparen. Ruhezustand Ruhezeit - Ruhezeit Kein Signal WLAN Maßeinheit auswählen Metrisch (cm, kg) Imperial (in, lb) - km/h - mph m ft Zaunbenachrichtigungen @@ -776,7 +436,6 @@ Nachricht eingeben Bitte bestätigen Sie weiterhin Ihre E-Mail-Adresse Code gültig für - Minuten Passwort erstellen E-Mail erfolgreich geändert! E-Mail ändern @@ -794,7 +453,6 @@ Verbinden Sie den Tracker mit dem Heim-WLAN (kein Passwort erforderlich). In der WLAN-Zone ist GPS deaktiviert. Das Gerät verbindet sich alle 10–60 Minuten mit dem Netzwerk und verbraucht dabei sehr wenig Energie. Wenn sich der Tracker außerhalb der WLAN-Zone befindet, wird GPS aktiviert und es erfolgt eine Netzwerkverbindung alle 3/5/10/15 Minuten. Tracker-Akkulaufzeit - Gehen Sie zu Haustier > Mein Haustier-Zaun > Verwalten > + Neu hinzufügen Standort auswählen und Radius oder Form anpassen. Zaun speichern, um ihn zu aktivieren. Benachrichtigungen bei Betreten oder Verlassen der Zone. Haustier-Zaun erstellen @@ -851,15 +509,11 @@ Wie erhält man das? Familieneinladung Aktive Zeit: - Ihr Freund - lädt dich zur - Familie ein. Ablaufdatum: Abgelaufen am: JAHRE MONATE TAGE - Automatische Verlängerung Abonnementbestellung Bestellnummer: Geben Sie Ihren Grund für die Rückerstattung ein @@ -869,14 +523,10 @@ Wird erstattet Erstattet /Jahr am - Verlängerung: /Monat am Ersatzgarantie - Rabattcode eingeben - Prüfen Jährlicher Schutz Jährlicher Schutz: - Bluetooth-Verbindung fehlgeschlagen LED-Lichteinstellungen Wenn sich der Tracker in der Nähe Ihres Smartphones befindet, empfehlen wir, ihn per Bluetooth zu verbinden und die LED-Einstellungen anzupassen. Die Änderungen werden sofort wirksam. Bluetooth-Einrichtung @@ -884,7 +534,7 @@ Doppeltes WLAN ist nicht zulässig Netzwerkeinrichtung Geben Sie das genaue Gewicht ein, um die Genauigkeit der Kalorienberechnung zu verbessern. - Automatische Verlängerung aktivieren + Verlängerung aktivieren Über das Gewicht Bestellung Premium festlegen @@ -923,31 +573,20 @@ Konto existiert bereits. Jetzt anmelden? Das ausgewählte Datum liegt außerhalb des gültigen Bereichs. Schütteln, um einzuschalten. \nBlinkendes grünes Licht bestätigt den Einschaltvorgang. - Gehen Sie zu „Haustier > Tracker“ \num Netzwerk \nGPS \nAkku \nWLAN-Zone \nBluetooth \n LED zu prüfen. \nGPS- und Mobilfunksignale können je nach Standort variieren. \nTesten Sie das Gerät vor der Nutzung an verschiedenen Orten. + GPS- und Mobilfunksignale können je nach Standort variieren. \nTesten Sie das Gerät vor der Verwendung an verschiedenen Standorten. Tracker wird geladen. Abonniert Baidu Maps Senden Zum Einschalten das Stromkabel anschließen. Nach dem ersten Start durch Schütteln einschalten. - 1-Jahres-Abonnement - 2-Jahres-Abonnement - 3-Jahres-Abonnement Ab nur Zahlungsverwaltung - Jährliche Abrechnung Basisplan Premium-Plan - Echtzeit-Tracking - Aktivitäts-/Ruheprotokolle - Notfallbenachrichtigungen Individuelle LED-Einstellungen Geofencing Routenverlauf - Freigabe für Familienmitglieder - 30-Tage-Rückgabegarantie - Das Programm hat eine Ausnahme und wird beendet Abonnement aktivieren - Ausgeschaltet Wird geladen Gesamtzeit Live funktioniert nur über Mobilfunk @@ -963,36 +602,298 @@ Ton Lokalisierung funktioniert nur über Mobilfunk Haustier ist nah, versuchen Sie Radar - Zum Laden ziehen - Zum Laden loslassen Vollständig geladen Zeitachse Halten Sie das Telefon nah am Gerät - Automatische Verlängerung: Kündigen + Abo: Aus Gestrichelte Linie anzeigen Erstverwendung Tägliche Nutzung Schlafmodus - 15 Minuten ohne Bewegung → Schlafmodus\nAutomatisches Aufwachen bei \nBewegung Akku-Updates alle 24 Stunden + 1. 15 Minuten ohne Bewegung → Schlafmodus.\n\n2. Automatisches Aufwachen bei. \n3. Bewegung\nAkku-Updates alle 24 Stunden. WiFi-Zone (Zuhause) - Mit Heim-WLAN verbinden -\nGPS aus → Akku sparen -\nUpdate ca. alle 60 Minuten - Haustier > Tracker > GPS-Update - \n3–15 Min auswählen - \nKurzes Intervall = höherer Akkuverbrauch - \nStandard: 5 Min + 1. Mit Heim-WLAN verbinden.\n\n2. GPS aus → Akku sparen.\n\n3. Update ca. alle 60 Minuten. + 1. Wählen Sie 3–15 Min.\n\n2. Kürzere Intervalle = höherer Akkuverbrauch.\n\n3. Standard: 5 Min. Zauntyp festlegen Sicherheitszone oder Sperrzone Grenze festlegen Benachrichtigungen aktivieren in Konto > Einstellungen > Benachrichtigungen Zaun im Bereich „Verwalten“ bearbeiten oder löschen - Gesamt Gerät wird initialisiert Fügen Sie eine WLAN-Zone hinzu, um die Nutzungsdauer zu verlängern Hinzufügen Bereits auf Mindestgröße + 3-Monats-Flex-Tarif + 1-Jahres-Plus-Tarif + 2-Jahres-Protection+-Tarif + Vierteljährliche Abrechnung + Jährliche Abrechnung + Abrechnung alle 2 Jahre + Anmelden mit + Meine Karte + Zahlung ändern + Gehen Sie zu + Haustier > Tracker + Haustier > Tracker > GPS-Aktualisierung + Haustier > Mein Haustierzaun > Verwalten > + Neu hinzufügen + Prüfen: + · Network\n· WiFi Zone\n· GPS + · Bluetooth\n· Akku\n· LED + Datenschutzrichtlinie + Ablaufdatum + Google Maps + Aktualisierung erfolgreich + Aktualisierung fehlgeschlagen + Bitte E-Mail-Adresse eingeben. + Tracker-ID eingeben + Kein Signal. Prüfen Sie, ob sich das Haustier im Innenbereich befindet. + Empfohlen + Ablaufzeit: + Aktivitäts-/Ruheprotokolle + Echtzeit-Tracking + Keine E-Mail erhalten? + %d Jahr + %d/100 Verdient + Letzte Aktualisierung: %s + Track & Punkte anzeigen + Möchten Sie die Daten des Haustiers wirklich mit \' %s \' teilen? + Bitte wählen Sie 2 bis 9 Fotos aus. + Verlängerung zu %.2f/Jahr danach & jederzeit kündbar + $%d Rabatt erhalten + Das Abonnement ist bis zum %s aktiv. + Die automatische Verlängerung ist deaktiviert. Das Abonnement endet am %s. + Speichern & Bestätigen + $%s/Monat + Sie haben Ihr Haustier erfolgreich eingerichtet und \ndas Sicherheits-Abzeichen erhalten! + Das Gerät ist bereits verknüpft. Bitte überprüfen Sie \ndie Eingabe und versuchen Sie es erneut. + %sft + %smph + Möchten Sie die Familie %s wirklich löschen? + Benachrichtigungen aktivieren: Gehen Sie zu „Konto“ > „Einstellungen“. Klicken Sie auf „Benachrichtigungen“ und aktivieren Sie sie. + Monat x%s + /%s Jahr + Stand: %s + Willkommen bei der Abbidot-App! Zum besseren Schutz Ihrer Rechte erläutern wir Ihnen in dieser Datenschutzerklärung, wie wir die von Ihnen bereitgestellten Informationen erfassen, verwenden, verarbeiten und schützen. Bitte lesen Sie die Datenschutzrichtlinie und die Nutzungsbedingungen sorgfältig durch. + Telefonnummer + Mit WeChat anmelden + Mit Bestätigungscode anmelden + Mit Apple anmelden + Mit Konto anmelden + Neues Passwort festlegen + Bestätigungscode gesendet + Mit Passwort anmelden + Hey, + Anmeldepasswort festlegen + Code anfordern + Wir haben den Bestätigungscode an deine E-Mail-Adresse gesendet + Bestätigungscode + Bitte lesen und akzeptieren Sie die + Nutzungsbedingungen + und die + Verknüpfen + Abgeschlossen + Daten + Meine Bestellungen + Hilfe-Center + Feedback + Einstellung + Sprache + Abmelden + Bitte wählen Sie eine Anfragenart aus + Geschlecht + Standort + Telefonnummer + Rasse + Aktivieren Sie das Gerät, um fortzufahren. + Aktivieren + Tracker + Mein Tracker + Autorisiert + Zaun + Einstellungen + Tage + LED-Licht + Zaun + Familie + Familienmitglied hinzufügen + Laden Sie Familienmitglieder ein, den Standort oder die Aktivitäten Ihres Haustiers zu teilen. Familienmitglieder können keine Zäune erstellen oder Einstellungen ändern. + Zurück + Ausschalten + Aktivitätsabzeichen + Karte auswählen + Gaode Maps + Die App ist nicht installiert. Bitte laden Sie die App zuerst herunter und installieren Sie sie. + Erfolgreich hinzugefügt + Erfolgreich gelöscht + Möchten Sie die Geräteverknüpfung wirklich aufheben? + Verknüpfung erfolgreich aufgehoben + Erfolgreich verknüpft + Meilen + kcal + Ihr Gerät ist abgelaufen. Bitte verlängern Sie es. + Karte wird geladen… + Hallo, leeres Fragment + Fotos und Videos + Auswählen + Vorschau + Es kann nur ein Dateityp ausgewählt werden. + Kamera konnte nicht gestartet werden. + Ungültiges Bild. + Dieses Bildformat wird nicht unterstützt + Löschen + Keine passenden Fotos + Keine passenden Videos + Original + Fertig + Abbrechen + Vorlage + Text + Datum + Doppeltippen zum Bearbeiten + Anpassen + Foto auswählen + GIF + Neue Karte hinzufügen + Zahlung + Abonnementplan: + Firmware-Update + Erfolgreich übermittelt + Erfolgreich gelöscht + Anmeldung fehlgeschlagen. Bitte versuchen Sie es erneut. + Name des Karteninhabers + KARTENINHABER + ABLAUFDATUM + Ungültiges Ablaufdatum + Ungültiges Kreditkartenformat + Möchten Sie das Gerät wirklich ausschalten? + Zuschneiden + Zum Beenden der App erneut drücken + Registrierung fehlgeschlagen + Ungültiges E-Mail-Format + Geräteverbindung trennen? + Verbindung erfolgreich + Verbindung fehlgeschlagen + Bitte geben Sie Ihre Mobiltelefonnummer ein. + Abbidot + Passwort zurücksetzen + Zahlung abbrechen + Der aktuelle Benutzer hat dieses Gerät bereits verknüpft. + Vorname + Nachname + Rechtliche Hinweise + Ich akzeptiere + Ablehnen + Keine Download-Adresse verfügbar + Bitte warten … + Versionsbeschreibung + Firmware-Name + Firmware-Dateigröße + Firmware herunterladen + DFU-Modus wird aktiviert + Suche nach DFU-Geräten + Verbindung zu Geräten wird hergestellt + Gerät erneut verbinden + Geräteverbindung getrennt + Aktualisierung läuft + Upgrade wird vorbereitet + Gerät erfolgreich verbunden + Batterie + Jan + Feb + Mär + Apr + Mai + Jun + Jul + Aug + Sep + Okt + Nov + Dez + Minimum + Gesamte Aktivitätsdistanz + Willkommen zurück + MM/JJ + CVC + Aktivieren + pro Jahr) + Sobald der Tracker erkennt, dass sich Ihr Haustier sicher in einer WLAN-Zone befindet, werden Live-Tracking, Licht und Ton deaktiviert, um die Akkulaufzeit zu verlängern. + Einladen + Dadurch werden alle Daten von + dauerhaft aus Ihrem Konto gelöscht. + Bluetooth + Suche … + 7-Tage-Durchschnitt + Schwaches GPS-Signal + Kein Netzwerksignal + Ruhezeit + km/h + mph + Ihr Freund + lädt dich zur + Familie ein. + Automatische Verlängerung + Verlängerung: + Notfallbenachrichtigungen + Freigabe für Familienmitglieder + 30-Tage-Rückgabegarantie + Das Programm hat eine Ausnahme und wird beendet + Ausgeschaltet + Zum Laden ziehen + Zum Laden loslassen + Gesamt Alle Haustiere anzeigen + Bitte geben Sie eine gültige Telefonnummer ein. + Konto + 1. Flexibler Kurzzeitschutz\n\n2. 30-Tage-Geld-zurück-Garantie + 1. Vorrangiger Kundensupport\n\n2. Jährlicher Schutz\n\n3. 30-Tage-Geld-zurück-Garantie + 1. Kostenloser Geräteaustausch (1×)\n\n2. Erweiterter Schutz\n\n3. Rundum-Schutz für Ihr Haustier\n\n4. 30-Tage-Geld-zurück-Garantie + %d Tracker + %d Haustiere + %d Zoll + Berechtigung konnte nicht abgerufen werden. + Keine Haustiere + Bitte verknüpfen Sie zuerst ein Haustier. + %d%% + %dY %dMo + Alle Videos + Abgeschlossen(%1$d/%2$d) + Es werden bis zu %d Fotos oder Videos unterstützt. + Es werden bis zu %d Fotos unterstützt. + Es werden bis zu %d Videos unterstützt. + The width of the photo should be greater than %1$d and the height should be greater than %1$d + Bitte gewähren Sie die entsprechenden Berechtigungen + Bitte gewähren Sie die entsprechenden Berechtigungen + %1$d/%2$d + Heute\t%s + Video auswählen + $\t%.2f + %s%% + Geben Sie die für Ihr Profil registrierte E-Mail-Adresse ein. \nWir senden einen 4-stelligen Bestätigungscode an Ihre \nE-Mail-Adresse. + $%s + $%s/Monat + $%s/Jahr + Dadurch werden alle Daten von %s dauerhaft aus Ihrem Konto gelöscht. + (Verlängert sich für $%s pro Jahr) + Aktivierung \nerfolgreich + Starte %s-minütiges LIVE + Code gültig für %ss + Ihr Freund %s lädt Sie ein, %s-Familienmitglied zu werden. + Verlängerung: $%s/year on %s + Verlängerung: $%s/month on %s + Jährlicher Geräteschutz + (Verlängerung zu $%s jährlich danach) + (Verlängerung danach für $%s pro Monat) + Fehler + Zahlungsmethode bearbeiten + Bitte Passwort eingeben. + Die ABBIDOT App sammelt Standortdaten. Die Route und die Entfernung zwischen dem aktuellen Standort und dem Gerät können berechnet werden. + (Verlängerung danach für $%s pro Tag) + (Verlängerung danach für $%s/%s Tage) + (Verlängerung danach für $%s/%s Jahre) + (Verlängerung danach für $%s/%s Monate) + Verlängerung: $%s/%s Jahre am %s + Verlängerung: $%s/%s Monate am %s terms_de.html privacy_de.html subscription_terms_conditions_de.html diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 620a801..9743093 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -1,49 +1,28 @@ - - Avez-vous reçu l\’e-mail ? Mesurez depuis le sol jusqu’au point le plus haut \ndes omoplates de votre animal Batterie : %s%% %s ans - %d an %d lb - %d/100 gagnés - Dernière fois: %s - Afficher Suivi & Point - Êtes-vous sûr de vouloir partager les données de l’animal avec \' %s \' ? - Veuillez sélectionner 2 \~ 9 photos - Renouvellement à %.2f par an ensuite, annulation à tout moment - $%d déjà de réduction - années de connexion d’abonnement - Le plan d’abonnement est actif jusqu’au %s - Le renouvellement automatique est désactivé et le plan d’abonnement ne sera plus disponible après le %s - Enregistrer & Confirmer Version%s Conditions générales Accepter la politique de confidentialité & Tles conditions. Le traceur est associé à %s Objectif d’activité Heure de fin - $%s/mois Adaptez la routine quotidienne de votre animal pour plus de plaisir avec une \ninteraction ciblée le matin et le soir, en tenant compte de ses \nbesoins, de son espèce et de sa race. +\tInviter Votre membre de famille ou ami partagé peut suivre la \nlocalisation de votre animal et ses données sans pouvoir les modifier. - Vous avez correctement configuré votre animal et vous avez \nobtenu le badge Sécurité ! Veuillez saisir le code à 4 chiffres envoyé à %s. - Temps restant: \t + Temps restant : \t En vous inscrivant, vous acceptez les Conditions générales et Confirmez que l’ID à 6 caractères correspond à celui \nsitué au dos du traceur. Localisez l’ID à 6 caractères au dos du \ntraceur. L’ID du traceur est incorrect, veuillez vérifier \net réessayer - Appareil déjà associé, veuillez vérifier \net réessayer Appairage\nréussi - Expire le (Renouvellement à Votre animal est-il à la maison ? - %s pi - %smph Dissocier %s - Êtes-vous sûr de vouloir supprimer la famille %s ? •\tNécessaire pour une synchronisation précise de l’activité. •\tAfficher votre propre position sur la carte\n•\tRequis pour synchroniser les données d’activité\n•\tAméliorer la précision du traceur •\tAutoriser les notifications pour suivre les informations importantes, comme si votre compagnon a quitté une zone sûre ou si vous devez charger votre appareil. @@ -52,14 +31,11 @@ Sélectionnez « Animal » > « Traceur ». Cliquez sur « Mise à jour GPS » Sélectionnez 3/5/10/15 minutes. (Des intervalles réseau plus courts déchargent plus rapidement la batterie du traceur. Par défaut, la reconnexion réseau se fait toutes les 15 minutes.) Lorsque le mode Live est activé, le traceur passe en mode de positionnement et de connexion rapide, généralement en 15 à 20 secondes. Ce mode consomme le plus de batterie et doit être réservé aux situations d’urgence. - 4. Activez les notifications : allez dans « Compte » > « Paramètres ». Cliquez sur « Notifications » et activez-les - Renouvellement : - /mois x%s - /%s an + Renouvellement: Le code de vérification sera envoyé à %s. Passez à Prime pour débloquer\ndes fonctionnalités exclusives ! Nouvelle version du firmware détectée : %s - « %s » vous invite à consulter « %s » + “%s” vous invite à consulter “%s” Votre abonnement a expiré,\nveuillez recharger %s clôtures définies %s est à proximité @@ -79,69 +55,16 @@ 1. 1 remplacement d’appareil inclus\n2. Assistance client dédiée\n3. Couverture de protection annuelle 1. Support VIP prioritaire\n2. Service de remplacement rapide (1 inclus)\n3. Protection renforcée\n4. Protection simplifiée pour votre animal %s min - À partir du %s %s min - En utilisant notre application, vous acceptez notre Politique de confidentialité et nos Conditions générales. Nous pouvons les mettre à jour occasionnellement - votre utilisation continue signifie que vous acceptez ces modifications. - Oui - Copyright © %d ABBIDOT Tous droits réservés - %d traceurs - %d animaux - %d po - Échec de l’obtention de l’autorisation - Aucun animal - Veuillez d’abord associer un animal - %d%% - %d an %d mois - Toutes les vidéos - Terminé(%1$d/%2$d) - Prend en charge jusqu’à %d photos ou vidéos - Prend en charge jusqu’à %d photos - Prend en charge jusqu’à %d vidéos - La largeur de la photo doit être supérieure à %1$d et la hauteur doit être supérieure à %1$d - Veuillez autoriser les permissions requises - Veuillez autoriser les permissions requises - %1$d/%2$d - Aujourd’hui\t%s - Sélection de vidéos - $\t%.2f - %s%% - Saisissez l’adresse e-mail enregistrée dans votre profil. Nous \nenverrons un code à 4 chiffres à votre e-mail. - $%s - $%s/mois - $%s/an - Cela supprimera définitivement toutes les données de %s de votre compte. - (Renouvellement à $%s par an) - Activation\nréussie - Lancement du direct de %s min - Code valide pendant %ss - Votre ami %s vous invite à rejoindre la famille %s. - Renouvellement : $%s/an le %s - Renouvellement : $%s/mois le %s - Protection annuelle - (Renouvellement à $%s par an par la suite) - (Renouvellement à $%s par mois par la suite) - Échec - Modifier le moyen de paiement - Aucun signal. Vérifiez si l’animal est à l’intérieur. Ce numéro de carte existe déjà. Le remplacer ? - Veuillez saisir le mot de passe. - Veuillez saisir l’adresse e-mail. Le Wi-Fi permet à votre traceur de rester connecté lorsque le signal LTE est faible. Renouvellement : $%s/%s jour le %s /jour x%s - ABBIDOT APP collecte les données de localisation. Le trajet et la distance entre la position actuelle et l’appareil peuvent être calculés. - (Renouvellement à $%s par jour par la suite) - (Renouvellement à $%s/%s jours par la suite) - (Renouvellement à $%s/%s ans par la suite) - (Renouvellement à $%s/%s mois par la suite) Protection annuelle %s an - Date d’expiration : 1 remplacement/an, quelle que soit la raison Radar Bluetooth Enregistré. Actif en ligne. - Renouvellement : $%s/%s ans le %s - Renouvellement : $%s/%s mois le %s Période de remboursement expirée Politique de remboursement\n Remboursement automatique (dans les 48 heures) @@ -150,329 +73,140 @@ Après la période initiale de 48 heures, les utilisateurs peuvent demander un remboursement dans les 30 jours suivant l’achat.\n\t1.Tous les forfaits d’abonnement (3 mois, 1 an, 2 ans) sont éligibles\n\t2.Les demandes de remboursement sont soumises à examen et approbation\n\t3.Les remboursements peuvent être partiellement ajustés en fonction de l’utilisation et de la consommation du service\n Les abonnements de plus de 30 jours ne sont pas remboursables. Aucun remboursement après 30 jours + Jardin + Parc + Jeu + Dangereux + Potager + Eau Bon retour E-mail - Téléphone Mot de passe Mot de passe oublié ? - Se connecter avec WeChat - Se connecter avec un code de vérification - Se connecter avec Apple - Se connecter avec un compte - Définir un nouveau mot de passe - Code de vérification envoyé Vous n\'avez pas de compte ? - Se connecter avec un mot de passe S\'inscrire - Bonjour, Retour à la connexion - Définir un mot de passe de connexion Nom complet - Obtenir - Nous avons envoyé le code de vérification à votre adresse e-mail - Code de vérification Suivant Renvoyer Continuer en acceptant. - Veuillez lire et accepter - et - Conditions d\'utilisation - Politique de confidentialité Soumettre - Association - Terminé - Données Carte Profil - Mes commandes - Centre d\'aide - Commentaires Paramètres - Paramètre Notification - Langue Compte À propos Vider le cache - Se déconnecter Commentaires Type de question (obligatoire) - À propos de l\'application - À propos du traceur + À propos + Appareil Autres Veuillez saisir votre problème ou suggestion - Veuillez sélectionner un type de question Veuillez laisser votre adresse e-mail afin que nous puissions vous aider plus rapidement Téléverser une image Nom - Sexe Date de naissance - Localisation E-mail - Téléphone - Race Poids Taille Comment mesurer la taille Enregistrer Étiquettes - Saisir l\'ID du traceur Activer - Activez l\'appareil pour continuer Non, merci - Activer Mon traceur - Traceurs - Mon traceur - Autorisé Lumière LED - Clôture - Paramètre Nouvel animal Dissocier Réseau GPS - Jours Bluetooth connecté Bluetooth non connecté - Lumière LED Désactivé Activé - Clôture - Famille - Ajouter un membre - Invitez votre famille à partager la localisation ou l\'activité de l\'animal. Les membres de la famille ne peuvent pas créer de clôtures ni modifier les paramètres. Inviter Envoyé avec succès - Retour Mises à jour GPS - Désactiver - Clôtures - Détails de la clôture Nom Forme Activer la clôture - Rayon Terminer - Actuel Continu Mode respiration - Clignotement lent Clignotement Mon animal - Animaux - Mes animaux - Autorisé Mâle Femelle - À propos Modifier - Badges d\'activité - Tous - Tout annuler - Batterie faible - Arrêter le suivi en direct - Le suivi en direct met à jour la position en temps réel, mais consomme davantage de batterie - Sélectionner une carte - Google Maps - Amap + Arrêter Annuler - L\'application n\'est pas installée, veuillez l\'installer d\'abord Temps d\'activité - Objectif - Distance Calories - Temps de suivi - Temps de sommeil - Temps d\'activité - Historique - Détails d\'activité Définir un objectif Modifier Actuel - Suivi - Point min - s mile kcal - jours Veuillez remplir tous les champs - Format d\'e-mail incorrect Réussi Téléversé avec succès - Ajouté avec succès Enregistré avec succès Connexion réussie Modifié avec succès Conseils Ajouter des clôtures - Modifier les clôtures - Mot de passe oublié Aucune donnée - Supprimé avec succès Êtes-vous sûr de vouloir supprimer ? - Êtes-vous sûr de vouloir dissocier l\'appareil ? - Dissociation réussie - Association réussie - Le poids doit être supérieur à 0 Aujourd\'hui min - s - mile - kcal jours - Votre appareil a expiré, veuillez le renouveler Arrêter le suivi en direct ? Supprimer Annuler - O Lun Oui Notifications - Tout sélectionner - Tout annuler Échec de la requête, veuillez réessayer - Chargement de la carte… - Inscription réussie - Bonjour fragment vide Toutes les photos - Photos et vidéos - Sélectionner - Aperçu - Un seul type de fichier peut être sélectionné - Impossible de démarrer l\'appareil photo - Image incorrecte Veuillez autoriser les permissions requises - Ce format d\'image n\'est pas pris en charge Modifier - Effacer - Aucune photo correspondante - Aucune vidéo correspondante - Original - Terminer - Annuler - Modèle - Texte - Date - Double-cliquez pour modifier - Personnaliser - Sélection de photos - GIF - Jours Renouvellement automatique : - Historique des recharges Recharger - Montant de la recharge - Détails de la commande - Sous-total - Coupon - Code promotionnel - Points Total général - Payer - Sélectionner un mode de paiement - Ajouter une nouvelle carte - Confirmer - Paiement - Paiement réussi - Échec du paiement, veuillez réessayer Réessayer Retour - Forfait d\'abonnement : - Période de paiement : - Date d\'expiration : - Français Êtes-vous sûr de vouloir vous déconnecter ? Confirmer la suppression du cache de l\'application ? Mode clair - Mise à jour du firmware - Soumis avec succès - Effacé avec succès Chargement… - Échec de la connexion. Veuillez réessayer Annuler le renouvellement automatique ? Confirmer ? - Renouvellement automatique annulé avec succès Le renouvellement automatique est pratique car il évite toute expiration Numéro de carte - Nom du titulaire - TITULAIRE DE LA CARTE - DATE D\'EXPIRATION MM/AA CVV - Veuillez sélectionner un mode de paiement - L\'utilisateur a annulé le paiement Paiement réussi Échec du paiement, veuillez réessayer - Date d\'expiration invalide - Format de carte bancaire invalide - Êtes-vous sûr de vouloir éteindre l\'appareil ? - Rogner Connexion au Bluetooth - Supprimer le compte La suppression de votre compte effacera définitivement toutes les données. Êtes-vous sûr ? - Compte supprimé avec succès - Appuyez à nouveau pour quitter l\'application Nom d\'utilisateur ou mot de passe incorrect Erreur de code de vérification Code de vérification expiré - Échec de l\'inscription L\'utilisateur n\'existe pas L\'utilisateur existe déjà - Format d\'e-mail incorrect - Déconnecter l\'appareil ? - Connexion réussie - Échec de la connexion - Activation réussie - Échec de l\'activation, veuillez réessayer - Première connexion - Veuillez associer votre numéro de téléphone - Veuillez saisir votre numéro de téléphone Réinitialiser le mot de passe - Passer une commande - $ - Jours restants d\'utilisation - Période de validité - Jours - Appareil - Réactiver - Montant total - Abbidot Politique de confidentialité Site web - Réinitialiser le mot de passe - Annuler le paiement Veuillez activer le Bluetooth du téléphone Vous ne pouvez pas partager avec vous-même - L\'utilisateur actuel a déjà associé cet appareil - Prénom - Nom En ligne Hors ligne - Informations légales - J\'accepte - Refuser - Aucune adresse de téléchargement - Voulez-vous télécharger le firmware et effectuer la mise à jour ? - Veuillez patienter… - Description de la version - Nom du firmware Version du firmware - Taille du fichier firmware Mettre à jour - Mise à jour réussie - Échec de la mise à jour - Télécharger le firmware - Entrée en mode DFU - Recherche des appareils DFU L\'appareil n\'existe pas - Connexion des appareils - Reconnecter l\'appareil - Appareil déconnecté Déconnecté - Mise à jour en cours - Préparation de la mise à jour - Appareil connecté avec succès Version déjà à jour Activité Parcours @@ -480,37 +214,28 @@ Plus KM Sommeil - Direct - Zone + Live Traceur Badges Voir tout Gérer Temps - Heure de début - Clôtures virtuelles Zone Wi-Fi Connecté Signal faible - Batterie Bluetooth Lumière - De - À Consulter le parcours et les points Tout lire Abonnement Aide Comment ça fonctionne - FAQ Paramètres des unités - Boutique Se déconnecter Calories moy. Temps moy. Données totales h - Distance totale 7 derniers jours 30 derniers jours OK @@ -526,21 +251,7 @@ Octobre Novembre Décembre - Jan - Fév - Mar - Avr - Mai - Juin - Juil - Aoû - Sep - Oct - Nov - Déc - Direction Plus le son s\'accélère, plus la distance est proche. - Vitesse Arrêter le radar Modifier la zone Wi-Fi Nom du Wi-Fi : @@ -555,12 +266,9 @@ Ajouter une zone interdite Modifier la zone interdite Tableau de bord - minimum - Recommandé h Définir un objectif quotidien Génial ! Prêt à commencer ! - Distance totale d\'activité km Temps d\'activité moyen quotidien Calories moyennes @@ -578,22 +286,16 @@ Membres Actif En attente - Relation Choisir un avatar - Ami - Amour Débloquez de nouveaux objectifs ! - Collègue Félicitations ! Partager Se connecter S\'inscrire Créer un compte - Politique de confidentialité. Minimum 6 caractères Pays Adresse e-mail - Bon retour Continuer Vérification OTP sec @@ -602,19 +304,15 @@ Réinitialiser maintenant Confirmer le mot de passe Mot de passe réinitialisé avec succès ! - Réinitialiser Standard Satellite Afficher les clôtures - Entrer Sélectionner Toujours à vos côtés ! Propulsé par Voir moins Voir tout Aventure - Social - Sportif Nouveau traceur Ajouter un nouveau traceur Charger et allumer @@ -634,19 +332,15 @@ Abonnement mensuel /mois /an - Meilleur rapport qualité-prix + Meilleur prix Confirmez votre forfait Numéro de l\'appareil Conditions générales - Renouvellement automatique - À propos du renouvellement automatique - Votre abonnement annuel sera automatiquement renouvelé à la fin de chaque période afin de garantir un service ininterrompu. Résumé Taxe - Total TTC Mode de paiement - Ma Carte - Aucune carte trouvée + Ma carte + Aucun moyen de paiement Ajouter une nouvelle carte Principale Effectuer le paiement @@ -654,19 +348,14 @@ Ajouter un mode de paiement Enregistrer la nouvelle carte Paiement réussi - MM/AA - CVC Cartes de paiement acceptées Définir comme carte principale Nom figurant sur la carte Autorisations Ignorer - Activer Accordez les autorisations pour une meilleure expérience. - Détails de l\'abonnement ID du traceur Forfait : - par an) Renouvellement le : Ajouter le lieu de résidence peut améliorer l\'autonomie et offrir une sécurité supplémentaire Créer une zone Wi-Fi @@ -674,26 +363,19 @@ Résidence permanente Choisir un réseau Wi-Fi Plus tard - Quelles unités de mesure utilisez-vous pour votre animal ? - Taille de votre animal - Longueur - Poids de votre animal Paramètres des notifications - Entrée ou sortie de la zone de sécurité / zone interdite + Entrer/quitter la zone sûre/interdite État du traceur - Avertissements d\'abonnement / batterie / extinction + Abonnement / Batterie faible / Éteindre Rappel d\'activité / sommeil / objectif atteint - Zone Wi-Fi À propos de la zone Wi-Fi Choisissez un réseau dans un endroit de confiance où votre animal passe beaucoup de temps, comme votre domicile. Une fois à portée, votre traceur reconnaîtra ce réseau comme une zone Wi-Fi. Bureau - Tant que votre traceur détecte que votre compagnon est en sécurité dans une zone Wi-Fi, le suivi LIVE, la lumière et le son resteront désactivés afin d\'économiser la batterie. Économiser la batterie À portée Bluetooth ? Localisez un traceur à proximité avec le Radar. Le mode LIVE sera également disponible, mais son utilisation mettra fin à l\'économie d\'énergie. Suivi de votre animal - Paramètres de la zone Wi-Fi + Réglages zone Wi-Fi Veuillez saisir vos commentaires - Veuillez laisser votre adresse e-mail afin que nous puissions vous aider plus rapidement Saisissez votre adresse e-mail Choisir un fichier Éteindre @@ -702,7 +384,6 @@ LED actuelle A quitté la zone de sécurité Dans la zone Wi-Fi - A quitté la zone Wi-Fi Dans la zone interdite Signal fort Zone Wi-Fi @@ -714,33 +395,22 @@ Vers ABBIDOT Les mots de passe saisis ne correspondent pas ! Aucun membre pour le moment - +Inviter Inviter des membres - Cela supprimera définitivement toutes les - données de votre compte. Accueil Durée LIVE À propos de la durée LIVE Le mode LIVE aide à retrouver les animaux grâce à des mises à jour de position toutes les 2 à 3 secondes, mais consomme davantage de batterie. Vous continuerez à recevoir des mises à jour régulières avec le suivi standard. Le suivi LIVE s\'arrêtera à la fin de la durée définie, mais vous pouvez l\'arrêter avant pour économiser la batterie. Rester bref - Bluetooth Localisation GPS Recevoir des notifications Activer Appareil non activé. Abonnez-vous pour l\'activer. - heures - Recherche en cours… Gardez le traceur allumé et à proximité pour le détecter. À l\'extérieur À l\'intérieur - Moyenne sur 7 jours - Arrêter le renouvellement automatique - Renouvellement automatique Vous avez créé trop de clôtures Le mode LIVE est terminé. La durée LIVE peut être définie dans les paramètres de durée LIVE. - Signal GPS faible - Aucun signal réseau Traceur éteint Démarrage du mode LIVE… Connexion au réseau @@ -753,14 +423,11 @@ Le suivi LIVE s\'arrêtera dans une heure, mais vous pouvez l\'arrêter avant pour économiser la batterie. Repos Temps de repos - Temps de repos Aucun signal Wi-Fi Sélectionner l\'unité de mesure Métrique (cm, kg) Impérial (po, lb) - km/h - mph m ft Alertes de clôture @@ -769,7 +436,6 @@ Saisir un message Veuillez poursuivre la vérification de votre adresse e-mail Code valide pendant - minutes Créer un mot de passe Adresse e-mail modifiée avec succès ! Modifier l\'adresse e-mail @@ -779,7 +445,7 @@ Hier Marche/Arrêt Chargez puis débranchez pour allumer. Le voyant vert clignotant indique que l\'appareil est allumé. - Choisissez un abonnement. \nAppuyez pour activer le traceur. \nActivez le GPS et le suivi cellulaire. + 1. Choisissez un abonnement. \n2. Appuyez pour activer le traceur. \n3. Activez le GPS et le suivi cellulaire. Activer le traceur (Les conditions GPS et réseau cellulaire peuvent varier selon l\'environnement. Avant de le placer sur votre animal, testez plusieurs emplacements pour évaluer la qualité du GPS et du réseau.) Vérifier l\'état du traceur @@ -787,7 +453,6 @@ Connectez le traceur au Wi-Fi domestique (aucun mot de passe requis). Dans la zone Wi-Fi, l\'activation GPS est désactivée. Il se connecte au réseau toutes les 10 à 60 minutes avec une consommation d\'énergie très faible. Lorsque votre traceur est hors de la zone Wi-Fi, il active le GPS et se connecte au réseau toutes les 3 / 5 / 10 / 15 minutes. Autonomie de la batterie du traceur - Allez dans Animal > Clôture de mon animal > Gérer > + Ajouter Choisissez un emplacement et ajustez le rayon ou la forme. Enregistrez la clôture pour l\'activer. Recevez des alertes lorsque l\'animal entre ou sort de la zone. Créer une clôture pour animal @@ -844,15 +509,11 @@ Comment l\'obtenir ? Invitation familiale Temps d\'activité : - Votre ami - vous invite à devenir - membre de la famille. Expire le : Expiré le : ANNÉES MOIS JOURS - Renouvellement automatique Commande d\'abonnement ID de commande : Saisissez la raison de votre remboursement @@ -862,14 +523,10 @@ Remboursement en cours Remboursé /an le - Renouvellement : /mois le Garantie de remplacement - Saisir un code de réduction - Vérifier Protection annuelle Protection annuelle : - Échec de la connexion Bluetooth Paramètres LED Lorsque le traceur est à côté de votre téléphone, il est recommandé de vous connecter via Bluetooth pour ajuster les paramètres LED. Les modifications prendront effet immédiatement. Configuration Bluetooth @@ -916,31 +573,20 @@ Ce compte existe déjà. Se connecter maintenant ? La date sélectionnée est hors plage autorisée Secouez pour allumer. \nLe voyant vert clignotant confirme l\'allumage. - Allez dans Animal > Traceur \n Vérifier Réseau GPS Batterie Zone Wi-Fi Bluetooth LED. \nLes signaux GPS et cellulaires peuvent varier selon l\'emplacement. \nTestez dans différents endroits avant utilisation. + Les signaux GPS et cellulaires peuvent varier selon l’emplacement. \nTestez l’appareil dans différents endroits avant utilisation. Le traceur est en charge Abonné Baidu Maps Envoyer Pour allumer, branchez le câble d\'alimentation. Après le premier démarrage, secouez pour allumer. - Abonnement 1 an - Abonnement 2 ans - Abonnement 3 ans À partir de Gestion des paiements - Facturé annuellement Forfait Basique Forfait Premium - Suivi en temps réel - Journal d\'activité et de repos - Notifications d\'urgence LED personnalisable Géorepérage Historique des trajets - Partage avec les membres de la famille - Garantie de retour de 30 jours - Le programme a rencontré une erreur et va se fermer Activer l\'abonnement - Éteint En charge Temps total LIVE fonctionne uniquement via le réseau cellulaire @@ -956,33 +602,300 @@ Son Localiser fonctionne uniquement via le réseau cellulaire L\'animal est proche, essayez le Radar - Tirer pour charger davantage - Relâcher pour charger Entièrement chargé Chronologie Gardez le téléphone proche de l\'appareil - Renouvellement automatique : annulé + Abonnement : Désactivé Afficher la ligne pointillée Première utilisation Utilisation quotidienne Mode veille - 15 minutes sans mouvement → mode veille. \nRéveil automatique en cas de mouvement. \nMise à jour de la batterie toutes les 24 heures. + 1. 15 minutes sans mouvement → mode veille. \n2. Réveil automatique en cas de mouvement. \n3. Mise à jour de la batterie toutes les 24 heures. Zone Wi-Fi (Maison) - Connexion au Wi-Fi domestique. \nGPS désactivé → économie de batterie. \nMise à jour toutes les ~60 minutes. - Animal > Traceur > Mise à jour GPS \nSélectionnez 3–15 min. \nIntervalle plus court = consommation plus élevée. \nPar défaut : 5 min. + 1. Connexion au Wi-Fi domestique. \n2. GPS désactivé → économie de batterie. \n3. Mise à jour toutes les ~60 minutes. + 1. Sélectionnez 3–15 min.\n\n2. Intervalle court = consommation de batterie plus élevée.\n\n3. Par défaut : 5 min. Définir le type de clôture Zone de sécurité ou zone interdite Définir la limite Activez les alertes dans Compte > Paramètres > Notifications Modifier ou supprimer une clôture dans Gérer - Total Initialisation de l\'appareil Ajouter une zone Wi-Fi pour prolonger la durée de protection Ajouter Taille minimale atteinte + Forfait Flex 3 mois + Forfait Plus 1 an + Forfait Protection+ 2 ans + Facturation trimestrielle + Facturation annuelle + Facturation tous les 2 ans + Se connecter avec + Ma Carte + Modifier le paiement + Accédez à + Animal > Tracker + Animal > Tracker > Mise à jour GPS + Animal > Ma clôture > Gérer > + Ajouter + Vérifiez: + · Réseau\n· Zone Wi-Fi\n· GPS + · Bluetooth\n· Batterie\n· LED + Politique de confidentialité + Expiré le + Google Maps + Mise à jour réussie + Échec de la mise à jour + Veuillez saisir l’adresse e-mail. + Saisir l\'ID du traceur + Aucun signal. Vérifiez si l’animal est à l’intérieur. + Recommandé + Date d’expiration : + Journal d\'activité et de repos + Suivi en temps réel + Avez-vous reçu l\’e-mail ? + %d an + %d/100 gagnés + Dernière fois : %s + Afficher Suivi & Point + Êtes-vous sûr de vouloir partager les données de l’animal avec \' %s \' ? + Veuillez sélectionner 2 \~ 9 photos + Renouvellement à %.2f par an ensuite, annulation à tout moment + $%d déjà de réduction + Le plan d’abonnement est actif jusqu’au %s + Le renouvellement automatique est désactivé et le plan d’abonnement ne sera plus disponible après le %s + Enregistrer & Confirmer + $%s/mois + Vous avez correctement configuré votre animal et vous avez \nobtenu le badge Sécurité ! + Appareil déjà associé, veuillez vérifier \net réessayer + %s pi + %smph + Êtes-vous sûr de vouloir supprimer la famille %s ? + 4. Activez les notifications : allez dans « Compte » > « Paramètres ». Cliquez sur « Notifications » et activez-les + /mois x%s + /%s an + À partir du %s + En utilisant notre application, vous acceptez notre Politique de confidentialité et nos Conditions générales. Nous pouvons les mettre à jour occasionnellement - votre utilisation continue signifie que vous acceptez ces modifications. + Téléphone + Se connecter avec WeChat + Se connecter avec un code de vérification + Se connecter avec Apple + Se connecter avec un compte + Définir un nouveau mot de passe + Code de vérification envoyé + Se connecter avec un mot de passe + Bonjour, + Définir un mot de passe de connexion + Obtenir + Nous avons envoyé le code de vérification à votre adresse e-mail + Code de vérification + Veuillez lire et accepter + et + Conditions d\'utilisation + Association + Terminé + Données + Mes commandes + Centre d\'aide + Commentaires + Paramètre + Langue + Se déconnecter + Veuillez sélectionner un type de question + Sexe + Localisation + Téléphone + Race + Activez l\'appareil pour continuer + Activer + Traceurs + Mon traceur + Autorisé + Clôture + Paramètre + Jours + Lumière LED + Clôture + Famille + Ajouter un membre + Invitez votre famille à partager la localisation ou l\'activité de l\'animal. Les membres de la famille ne peuvent pas créer de clôtures ni modifier les paramètres. + Retour + Désactiver + Badges d\'activité + Sélectionner une carte + Amap + L\'application n\'est pas installée, veuillez l\'installer d\'abord + Ajouté avec succès + Supprimé avec succès + Êtes-vous sûr de vouloir dissocier l\'appareil ? + Dissociation réussie + Association réussie + mile + kcal + Votre appareil a expiré, veuillez le renouveler + Chargement de la carte… + Bonjour fragment vide + Photos et vidéos + Sélectionner + Aperçu + Un seul type de fichier peut être sélectionné + Impossible de démarrer l\'appareil photo + Image incorrecte + Ce format d\'image n\'est pas pris en charge + Effacer + Aucune photo correspondante + Aucune vidéo correspondante + Original + Terminer + Annuler + Modèle + Texte + Date + Double-cliquez pour modifier + Personnaliser + Sélection de photos + GIF + Ajouter une nouvelle carte + Paiement + Forfait d\'abonnement : + Mise à jour du firmware + Soumis avec succès + Effacé avec succès + Échec de la connexion. Veuillez réessayer + Nom du titulaire + TITULAIRE DE LA CARTE + DATE D\'EXPIRATION + Date d\'expiration invalide + Format de carte bancaire invalide + Êtes-vous sûr de vouloir éteindre l\'appareil ? + Rogner + Appuyez à nouveau pour quitter l\'application + Échec de l\'inscription + Format d\'e-mail incorrect + Déconnecter l\'appareil ? + Connexion réussie + Échec de la connexion + Veuillez saisir votre numéro de téléphone + Abbidot + Réinitialiser le mot de passe + Annuler le paiement + L\'utilisateur actuel a déjà associé cet appareil + Prénom + Nom + Informations légales + J\'accepte + Refuser + Aucune adresse de téléchargement + Veuillez patienter… + Description de la version + Nom du firmware + Taille du fichier firmware + Télécharger le firmware + Entrée en mode DFU + Recherche des appareils DFU + Connexion des appareils + Reconnecter l\'appareil + Appareil déconnecté + Mise à jour en cours + Préparation de la mise à jour + Appareil connecté avec succès + Batterie + Jan + Fév + Mar + Avr + Mai + Juin + Juil + Aoû + Sep + Oct + Nov + Déc + minimum + Distance totale d\'activité + Bon retour + MM/AA + CVC + Activer + par an) + Tant que votre traceur détecte que votre compagnon est en sécurité dans une zone Wi-Fi, le suivi LIVE, la lumière et le son resteront désactivés afin d\'économiser la batterie. + +Inviter + Cela supprimera définitivement toutes les + données de votre compte. + Bluetooth + Recherche en cours… + Moyenne sur 7 jours + Signal GPS faible + Aucun signal réseau + Temps de repos + km/h + mph + Votre ami + vous invite à devenir + membre de la famille. + Renouvellement automatique + Renouvellement : + Notifications d\'urgence + Partage avec les membres de la famille + Garantie de retour de 30 jours + Le programme a rencontré une erreur et va se fermer + Éteint + Tirer pour charger davantage + Relâcher pour charger + Total Afficher tous les animaux + Veuillez saisir un numéro de téléphone valide. + Compte + 1. Protection flexible à court terme\n\n2. Garantie satisfait ou remboursé de 30 jours + 1. Assistance client prioritaire\n\n2. Protection annuelle\n\n3. Garantie satisfait ou remboursé de 30 jours + 1. Remplacement gratuit de l\'appareil (1×)\n2. Protection renforcée\n3. Protection de votre animal en toute simplicité\n4. Garantie satisfait ou remboursé de 30 jours + Copyright © %d ABBIDOT Tous droits réservés + %d traceurs + %d animaux + %d po + Échec de l’obtention de l’autorisation + Aucun animal + Veuillez d’abord associer un animal + %d%% + %d an %d mois + Toutes les vidéos + Terminé(%1$d/%2$d) + Prend en charge jusqu’à %d photos ou vidéos + Prend en charge jusqu’à %d photos + Prend en charge jusqu’à %d vidéos + La largeur de la photo doit être supérieure à %1$d et la hauteur doit être supérieure à %1$d + Veuillez autoriser les permissions requises + Veuillez autoriser les permissions requises + %1$d/%2$d + Aujourd’hui\t%s + Sélection de vidéos + $\t%.2f + %s%% + Saisissez l’adresse e-mail enregistrée dans votre profil. Nous \nenverrons un code à 4 chiffres à votre e-mail. + $%s + $%s/mois + $%s/an + Cela supprimera définitivement toutes les données de %s de votre compte. + (Renouvellement à $%s par an) + Activation\nréussie + Lancement du direct de %s min + Code valide pendant %ss + Votre ami %s vous invite à rejoindre la famille %s. + Renouvellement : $%s/an le %s + Renouvellement : $%s/mois le %s + Protection annuelle + (Renouvellement à $%s par an par la suite) + (Renouvellement à $%s par mois par la suite) + Échec + Modifier le moyen de paiement + Veuillez saisir le mot de passe. + ABBIDOT APP collecte les données de localisation. Le trajet et la distance entre la position actuelle et l’appareil peuvent être calculés. + (Renouvellement à $%s par jour par la suite) + (Renouvellement à $%s/%s jours par la suite) + (Renouvellement à $%s/%s ans par la suite) + (Renouvellement à $%s/%s mois par la suite) + Renouvellement : $%s/%s ans le %s + Renouvellement : $%s/%s mois le %s terms_fr.html privacy_fr.html subscription_terms_conditions_fr.html - \ No newline at end of file diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index ed37363..78104e2 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -43,43 +43,29 @@ - - 从地面测量到宠物肩胛骨的最高点 电量:%s%% %s年 - - 更新时间:%s - - - 请选择2 \~ 9张照片 - + %d磅 版本%s 服务协议 接受隐私政策与条款。 该设备已被%s绑定 运动目标 结束时间 - 为宠物定制每日趣味活动,专注早晚互动,兼顾其需求、物种与品种 +\t邀请 共享的家庭成员可查看宠物位置和日期,但无法编辑 - 请输入发送至 %s 的4位数验证码 剩余时间:\t - + 注册即表示接受服务条款和隐私政策 确认6字符ID与追踪器背面一致 在设备背面找到6位数ID 设备ID错误,请核对后重试 - 配对成功 - 有效期至 (续订价 这是您宠物的常驻地吗? - - 解绑 %s - 您确定要删除家庭成员%s •\t 确保活动数据同步准确的必要条件。 •\t 在地图上显示您自己的位置 \n•\t 同步活动数据所必需 \n•\t 提升追踪器精度 •\t 允许接收通知以掌握重要信息,例如您的爱宠是否离开了安全区域,或者您是否该考虑为设备充电了。 @@ -88,10 +74,7 @@ 选择“宠物” > “追踪器” ,点击“GPS更新间隔” ,选择3/5/10/15分钟。 (更短的网络连接间隔会更快耗尽设备电量。默认情况下,网络每15分钟重新连接一次。) 当直播开启时,追踪器进入快速定位和联网状态,通常在15-20秒内完成。此模式耗电最快,因此最好仅在紧急情况下使用。 - 续费: - /月 x%s - 将发送验证码至 %s 升级至高级版,解锁独家功能! 检测到新固件版本:%s @@ -115,67 +98,16 @@ 1.设备1次更换\n2. 专属客户支持\n3. 年度保障服务 1. VIP 优先支持\n2. 快速更换服务(含1次)\n3. 增强型保障\n4. 无忧宠物保护 %s 分钟 - %s 分钟 - 欢迎使用爱彼宠物!为了更好地保障您的权益,我们将在本《隐私政策》声明中向您说明我们如何收集、使用、处理和保障您提供给我们的信息。请仔细阅读《隐私政策》和《服务条款》。 是的 - %d个设备 - %d只 - %d 英寸 - 未能获得许可 - 无宠物 - 请先绑定宠物 - %d%% - %d年%d月 - 全部视频 - 完成(%1$d/%2$d) - 最多支持%d个图片或视频 - 最多支持%d个图片 - 最多支持%d个视频 - 照片的宽度应大于%1$d,高度应大于%1$d - 请允许相关权限 - 请允许相关权限 - %1$d/%2$d - 今天\t%s - 选择视频 - ¥\t%.2f - %s%% - 输入您档案的注册邮箱,我们将发送4位数验证码至该邮箱 - $%s - $%s/月 - $%s/年 - 这将从您的账户中永久删除所有 %s 数据 - (按每年 $%s 续订) - 激活成功! - 正在启动 %s-分钟直播 - 验证码有效期为 %ss - 您的朋友 %s 邀请您成为 %s 的家人。 - 续费:$%s/年,于%s - 续费:$%s/月,于%s - 年度保险 - (此后按每年 $%s 续订) - (此后按每月 $%s 续订) - 失败 - 编辑付款方式 - 无信号。请检查宠物是否在室内。 卡号已存在。是否覆盖? - 请输入密码。 - 请输入邮箱。 当移动信号弱时,Wi-Fi可确保设备保持连接 续费:$%s/%s天,于%s /天 x%s - ABBIDOT应用收集位置数据,可计算当前位置与设备之间的路线和距离。 - (之后按$%s每天续费) - (之后按$%s/%s天续费) - (之后按$%s/%s年续费) - (之后按$%s/%s月续费) %s 年保险 - 到期时间: 1年 1 次无理由换新 蓝牙雷达 已保存,上线时生效。 - 续订:$%s / %s 年,于 %s - 续订:$%s / %s 月,于 %s 退款期限已过 退款政策\n 自动退款(48小时内) @@ -184,128 +116,77 @@ 在最初的48小时之后,用户可在购买后30天内申请退款。\n\t1. 所有订阅计划(3个月、1年、2年)均符合条件\n\t2. 退款申请需经过审核和批准\n\t3. 退款可能会根据使用情况和服务消耗进行部分调整\n 超过30天的订阅不可退款。 30天后不退款 + 花园 + 公园 + 玩耍 + 不安全 + 菜园 + 水域 欢迎 邮箱 - 手机号 密码 忘记密码? - 微信登录 - 验证码登录 - - - 验证码已发送 没有账号? - 注册 - 返回登录 - 昵称 - 下一步 重新发送 同意《服务协议》和《隐私政策》 - 请阅读并同意 - 和 - 《服务协议》 - 《隐私政策》 提交 - - 地图 我的 - - - 反馈中心 设置 - 消息中心 - 帐户 关于 清除缓存 - 反馈中心 问题类型(必填) 关于APP 关于设备 其它 请输入您的问题或建议 - 请选择问题类型 请留下您的邮箱,以便我们更快地帮助您 上传图片 名称 - 生日 - 邮箱 - - 品种 体重 肩高 如何测量身高 保存 标签 - 激活 - 不用了,谢谢 - 我的设备 - - 我的设备 - LED灯 - - 新宠物 解绑 网络 GPS - 蓝牙已连接 蓝牙未连接 - LED灯 关 开 - - 家人 - 邀请 发送成功 - 返回 追踪间隔 - 名称 形式 启用围栏 - 完成 - 常亮 呼吸 - 快闪 我的宠物 - 雄 雌 - 编辑 - 活动勋章 - 停止直播 - - 选择地图 - 谷歌地图 - 高德地图 取消 - APP未安装,请先下载安装 运动时间 - - 卡路里 - 设置目标 修改 当前 @@ -315,24 +196,16 @@ 请完整填写 成功 上传成功 - 添加成功 保存成功 登录成功 修改成功 提示 添加围栏 无数据 - 成功删除 确定要删除? - 确定要解绑设备? - 解绑成功 - 绑定成功 今天 分钟 - 英里 - 大卡 天 - 您的设备已过期,请充值 停止直播? 删除 取消 @@ -340,110 +213,43 @@ 确定 通知 请求失败,请重试 - 地图加载中… - 你好,空白片段 全部图片 - 图片和视频 - 选择 - 预览 - 只能选择一种类型的文件 - 无法启动相机 - 图片错误 请允许相关权限 - 不支持该图像格式 编辑 - 清除 - 没有匹配的照片 - 没有匹配的视频 - 原始 - 完成 - 取消 - 模板 - 文本 - 日期 - 双击编辑 - 自定义 - 选择照片 - GIF 自动订阅: 充值 总计 - 添加新卡 - 支付详情 重试 返回 确定要退出登录吗? 确定要清除缓存? 灯光模式 - 固件升级 - 提交成功 - 清除成功 加载中... - 登录失败,请重新登录 确定要取消自动订阅? 自动订阅更方便,因为您不必担心订阅过期 卡号 - 持卡人姓名 - 持卡人 - 截止日期 MM/YY CVV 支付成功 支付失败,请重试 - 失效日期 - 信用卡格式无效 - 您确定要关闭设备吗? - 裁剪图片 连接中… 注销账户将删除账户下所有的数据,是否继续? - 再次返回退出程序 用户名或密码错误 验证码错误 验证码已过期 - 注册失败 用户不存在 用户已存在 - 邮箱格式不对 - 是否断开连接设备? - 连接成功 - 连接失败 - 请输入手机号 找回密码 - 爱彼宠物 隐私政策 官网 - 修改密码 - 取消支付 请打开手机蓝牙 不能分享给自己 - 当前用户已经绑定该设备 - 姓 - 名 在线 离线 - 法律信息 - 我接受 - 拒绝 - 没有下载地址 - 请稍等… - 版本说明 - 固件名称 固件版本 - 固件大小 升级 - 升级成功 - 升级失败 - 下载固件 - 进入DFU模式 - 搜索DUF设备 设备不存在 - 连接设备 - 重连设备 - 设备已断开 断开连接 - 升级中 - 准备升级 - 设备连接成功 已是最新版本 运动 历史 @@ -460,7 +266,6 @@ WiFi区域 已连接 信号弱 - 电量 蓝牙 指示灯 检查轨迹和地点 @@ -489,18 +294,6 @@ 十月 十一月 十二月 - 1月 - 2月 - 3月 - 4月 - 5月 - 6月 - 7月 - 8月 - 9月 - 10月 - 11月 - 12月 声音传播速度加快时,距离更近。 停止雷达 编辑WiFi区域 @@ -516,12 +309,9 @@ 添加禁止区域 编辑禁止区域 数据面板 - 最小值 - 推荐值 小时 设置每日目标 太棒了!开始吧! - 活动总距离 公里 日均活动时长 平均卡路里 @@ -549,7 +339,6 @@ 至少6个字符 国家/地区 电子邮箱 - 欢迎回来 继续 验证码 秒 @@ -586,15 +375,15 @@ 月付 /月 /年 - 热门 + 超值 确认您的套餐 设备编号 条款与条件 摘要 税费 支付方式 - 我的卡片 - 未找到卡片 + 选择卡片 + 没有支付信息 添加新卡片 主要支付方式 立即支付 @@ -602,18 +391,14 @@ 添加支付方式 保存新卡片 支付成功 - 月/年 (MM/YY) - 安全码 (CVC) 接受的支付卡 设为主要卡片 持卡人姓名 权限 跳过 - 启用 授予权限以提升体验。 设备ID 套餐: - 续订日期: 添加常驻地可提升电池续航并提供额外安全保障 建立WiFi区域 @@ -629,7 +414,6 @@ 关于WiFi区域 在您宠物常驻地(如家中)选择一个网络。一旦进入覆盖范围,您的设备将识别此网络为WiFi区域。 办公室 - 只要设备检测到您的爱宠处于WiFi区域内,就会关闭实时追踪以延长电池续航。 省电模式 在蓝牙范围内?可使用雷达精确定位附近y设备。实时追踪也将可用,但使用它会结束省电模式。 正在追踪您的宠物 @@ -654,30 +438,22 @@ 发送至ABBIDOT 输入的密码不一致! 尚无成员 - +邀请 邀请成员 - - 家 直播时长 关于直播时长 直播模式可帮助寻找宠物,每2~3秒更新一次位置,但会消耗更多电量。默认追踪仍会提供常规更新。 直播将在设定的时长结束时停止,但您也可以提前停止以节省电量。 请尽量缩短时长 - 蓝牙 GPS 位置 接收通知 开启 设备未激活。请订阅后激活。 - 正在搜索… 请保持设备开机并靠近扫描。 区域外 区域内 - 7日均值 创建的围栏太多了 直播已结束。直播时长可通过“直播时长”设置。 - GPS信号弱 - 无网络信号 设备已关机 正在启动直播… 正在连接网络 @@ -690,14 +466,11 @@ 直播将在一小时后停止,但您也可以提前停止以节省电量。 休息中 休息时长 - 休息时间 无信号 WiFi 选择计量单位 - 公制 (厘米, 千克) + 公制 (厘米, 千克) 英制 (英寸, 磅) - 公里/小时 (km/h) - 英里/小时 (mph) 米 (m) 英尺 (ft) 围栏告警 @@ -715,7 +488,7 @@ 昨天 开机/关机 充电后拔掉电源即可开机。 \n绿灯闪烁 = 已开机。 - 选择一个订阅 \n点击以激活追踪器 \n启用GPS和蜂窝网络追踪。 + 1. 选择一个订阅.\n2. 点击以激活追踪器 \n3. 启用GPS和蜂窝网络追踪。 激活追踪器 (GPS和移动网络状态可能因环境而异。在给宠物佩戴前,请检查您周围的不同位置以评估GPS和网络状态。) 检查设备状态 @@ -723,7 +496,6 @@ 将设备连接到家庭WiFi(无需密码)。在WiFi区域内,GPS将停止工作。每10-60分钟连接一次网络,功耗极低。 当您的追踪器在WiFi区域外时,它会激活GPS并每3/5/10/15分钟连接一次网络。 设备电池续航 - 前往“宠物” > “我的宠物围栏” > “管理” > “+ 新增” 定义边界:在地图上选择一个位置,调整围栏的半径或形状。 当宠物进入或离开区域时发出警报。 创建宠物围栏 @@ -780,14 +552,11 @@ 如何获取? 邀请家人 活跃时长: - - 有效期至: 过期于: 年 月 - - + 天 订阅订单 订单号: 请输入您的退款原因 @@ -796,8 +565,9 @@ 等待处理 退款中 已退款 - - + /年,于 + /月,于 + 换新保障 年度护理 年度护理: LED灯设置 @@ -846,31 +616,20 @@ 账户已存在。立即登录? 所选日期超出范围 摇一摇开机 \n绿灯闪烁表示已开机。 - 前往“宠物 > 追踪器” \n检查:网络、GPS、电池、WiFi、区域、蓝牙、LED。 \nGPS和蜂窝网络信号可能因位置而异。使用前请在不同位置进行测试。 + GPS 和蜂窝网络信号可能因位置而异。\n使用前,请在不同位置进行测试。 设备充电中 已订阅 百度地图 发送 首次开机请连接电源线。之后可通过摇动开机。 - 1年订阅 - 2年订阅 - 3年订阅 低至 支付管理 - 按年计费 基础计划 高级计划 - 实时追踪 - 活动/休息 - 告警日志 自定义LED灯 电子围栏 路线历史记录 - 家庭成员共享 - 30天退款保证 - 程序出现异常,即将退出 激活订阅 - 已关机 充电中 总时间 直播仅限移动网络 @@ -886,8 +645,6 @@ 提示音 定位仅适用于移动网络 宠物在附近,请尝试雷达 - 下拉加载更多 - 释放加载 已充满电 时间线 保持手机靠近设备 @@ -896,26 +653,292 @@ 首次使用 日常使用 休眠模式 - 15分钟无移动 → 进入休眠模式。 \n移动时自动唤醒。 \n电量每24小时更新一次 + 1. 15分钟无移动 → 进入休眠模式; \n2. 移动时自动唤醒; \n3. 电量每24小时更新一次。 WiFi区域(家) - 连接家庭WiFi \n GPS关闭 → 节省电池。\n约每60分钟更新一次 - 宠物 > 追踪器 > GPS更新 \n选择3–15分钟。 \n间隔越短,耗电越高。 \n默认:5分钟 + 1. 连接家庭WiFi; \n2. GPS关闭 → 节省电池;\n3. 约每60分钟更新一次。 + 1. 选择 3–15 分钟。\n\n2. 间隔越短,耗电越高。\n\n3. 默认:5 分钟。 设置围栏类型 安全区域 或 禁止区 设置边界 在“账户 > 设置 > 通知”中启用提醒 在“管理”中编辑或删除围栏 - 总计 正在初始化设备 添加wifi区域可延长使用时长 去添加 已是最小尺寸 + 3个月灵活套餐 + 1年Plus套餐 + 2年Protection+套餐 + 按季度计费 + 按年计费 + 每两年计费 + 使用以下方式登录 + 我的卡片 + 编辑支付信息 + 该手机号码已被绑定 + 前往 + 宠物 > 定位器 + 宠物 > 定位器 > GPS 更新 + 宠物 > 我的宠物围栏 > 管理 > + 新增 + 检查: + · 网络\n· WiFi Zone\n· GPS + · 蓝牙\n· 电量\n· LED + 《隐私政策》 + 过期于 + 谷歌地图 + 升级成功 + 升级失败 + 请输入邮箱。 + 输入设备ID + 无信号。请检查宠物是否在室内。 + 推荐值 + 到期时间: + 活动/休息 + 实时追踪 + 还没有收到验证码? + %d年 + %d/100 已获得 + 更新时间:%s + 显示轨迹/点 + 确定要分享\'%s\'的宠物数据 + 请选择2 \~ 9张照片 + 此后以%.2f/年续订,可随时取消 + 已优惠%d + 订阅计划有效期至%s + 自动续订已关闭,订阅计划将在%s之后不可用 + 保存并确认 + $%s/月 + 宠物信息设置成功,获得安全徽章! + 设备已被绑定,请核对后重试 + %s英尺 (ft) + %s英里/小时 (mph) + 您确定要删除家庭成员%s + 开启通知:前往“账户” > \"设置\"。点击\"通知\"并开启。 + /月 x%s + /%s 年 + 截止至%s + 欢迎使用爱彼宠物!为了更好地保障您的权益,我们将在本《隐私政策》声明中向您说明我们如何收集、使用、处理和保障您提供给我们的信息。请仔细阅读《隐私政策》和《服务条款》。 + 手机号 + 微信登录 + 验证码登录 + Apple登录 + 账号登录 + 设置新密码 + 验证码已发送 + 密码登录 + 嗨, + 设置密码 + 获取 + 我们已将验证码发送到您的电子邮件 + 验证码 + 请阅读并同意 + 和 + 《服务协议》 + 绑定 + 完成 + 数据 + 我的订单 + 帮助中心 + 反馈中心 + 设置 + 语言 + 退出登录 + 请选择问题类型 + 性别 + 地点 + 手机 + 品种 + 激活并继续 + 激活 + 设备 + 我的设备 + 被授权的 + 围栏 + 设置 + 天 + LED灯 + 围栏 + 家人 + 添加家人 + 邀请您的家人分享宠物的位置或活动。 家庭成员不能创建围栏或修改设置。 + 返回 + 关机 + 活动勋章 + 选择地图 + 高德地图 + APP未安装,请先下载安装 + 添加成功 + 成功删除 + 确定要解绑设备? + 解绑成功 + 绑定成功 + 英里 + 大卡 + 您的设备已过期,请充值 + 地图加载中… + 你好,空白片段 + 图片和视频 + 选择 + 预览 + 只能选择一种类型的文件 + 无法启动相机 + 图片错误 + 不支持该图像格式 + 清除 + 没有匹配的照片 + 没有匹配的视频 + 原始 + 完成 + 取消 + 模板 + 文本 + 日期 + 双击编辑 + 自定义 + 选择照片 + GIF + 添加新卡 + 支付详情 + 订阅计划: + 固件升级 + 提交成功 + 清除成功 + 登录失败,请重新登录 + 持卡人姓名 + 持卡人 + 截止日期 + 失效日期 + 信用卡格式无效 + 您确定要关闭设备吗? + 裁剪图片 + 再次返回退出程序 + 注册失败 + 邮箱格式不对 + 是否断开连接设备? + 连接成功 + 连接失败 + 请输入手机号 + 爱彼宠物 + 修改密码 + 取消支付 + 当前用户已经绑定该设备 + 姓 + 名 + 法律信息 + 我接受 + 拒绝 + 没有下载地址 + 请稍等… + 版本说明 + 固件名称 + 固件大小 + 下载固件 + 进入DFU模式 + 搜索DUF设备 + 连接设备 + 重连设备 + 设备已断开 + 升级中 + 准备升级 + 设备连接成功 + 电量 + 1月 + 2月 + 3月 + 4月 + 5月 + 6月 + 7月 + 8月 + 9月 + 10月 + 11月 + 12月 + 最小值 + 活动总距离 + 欢迎回来 + 月/年 (MM/YY) + 安全码 (CVC) + 启用 + /年) + 只要设备检测到您的爱宠处于WiFi区域内,就会关闭实时追踪以延长电池续航。 + +邀请 + 这将从您的账户中永久删除所有 + 数据 + 蓝牙 + 正在搜索… + 7日均值 + GPS信号弱 + 无网络信号 + 休息时间 + 公里/小时 (km/h) + 英里/小时 (mph) + 您的朋友 + 邀请您成为 + 的家人。 + 自动续费 + 续费: + 告警日志 + 家庭成员共享 + 30天退款保证 + 程序出现异常,即将退出 + 已关机 + 下拉加载更多 + 释放加载 + 总计 显示所有宠物 - 请使用有效的手机号码 + 请输入有效的电话号码 账户 + 1. 灵活短期保障\n\n2. 30天退款保证 + 1. 专属客户支持\n\n2. 全年保障\n\n3. 30天退款保证 + 1. 免费设备更换(1次)\n\n2. 增强保障\n\n3. 宠物无忧保障\n\n4. 30天退款保证 + %d个设备 + %d只 + %d 英寸 + 未能获得许可 + 无宠物 + 请先绑定宠物 + %d%% + %d年%d月 + 全部视频 + 完成(%1$d/%2$d) + 最多支持%d个图片或视频 + 最多支持%d个图片 + 最多支持%d个视频 + 照片的宽度应大于%1$d,高度应大于%1$d + 请允许相关权限 + 请允许相关权限 + %1$d/%2$d + 今天\t%s + 选择视频 + ¥\t%.2f + %s%% + 输入您档案的注册邮箱,我们将发送4位数验证码至该邮箱 + $%s + $%s/月 + $%s/年 + 这将从您的账户中永久删除所有 %s 数据 + (按每年 $%s 续订) + 激活成功! + 正在启动 %s-分钟直播 + 验证码有效期为 %ss + 您的朋友 %s 邀请您成为 %s 的家人。 + 续费:$%s/年,于%s + 续费:$%s/月,于%s + 年度保险 + (此后按每年 $%s 续订) + (此后按每月 $%s 续订) + 失败 + 编辑付款方式 + 请输入密码。 + ABBIDOT应用收集位置数据,可计算当前位置与设备之间的路线和距离。 + (之后按$%s每天续费) + (之后按$%s/%s天续费) + (之后按$%s/%s年续费) + (之后按$%s/%s月续费) + 续订:$%s / %s 年,于 %s + 续订:$%s / %s 月,于 %s terms_zh.html privacy_zh.html subscription_terms_conditions_zh.html - 该手机号码已被绑定 - \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7d88cdd..d23cb54 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -100,50 +100,29 @@ - - Haven\’t received the email? Measure form the floor up to the highest spot of your \npet’s shoulder blades Battery: %s%% %s Years - %d Year %d lb - %d/100 Earned - Last Time: %s - Show Track & Point - Are you sure you want to share the pet’s data with \' %s \'? - Please select 2 \~ 9 photos - Renew at %.2f per year thereafter, cancel anytime - $%doff already - %d Years connection subscription - The subscription plan is active until %s - Auto-renewal is off and the subscription plan will not be available after %s - Save & Confirm Version%s Terms & Conditions Accept Privacy Policy & Terms. The tracker is paired with %s Activity Goal End Time - $%s/month Tailor your pet\'s daily routine for enjoyment with \nfocused morning and evening engagement, considering \ntheir needs, species, and breed. +\tInvite Your shared family member or friend can track your \npet’s location and date without the ability to edit them. - You have successfully setup your pet and you \nearned the Safety badge! Please enter the 4-digit code sent to %s. Time remaining:\t By registering, you accept the Terms & Conditions and Confirm the 6-character ID matches the one \non the back of the tracker. Locate the 6-character ID on the back of \nthe tracker. The Tracker ID is error, please verify \nand try again - Device already bound, please verify \nand try again Successfully\nPaired - Expires On - (Renew at + (Renew at Is this your pet\'s home? - %sft - %smph Unassign %s - Are you sure you want to delete the family %s? •\tNecessary for accurate activity syncing. •\tShow your own location on the map\n•\tRequired to sync activity data\n•\tEnhance tracker accuracy •\tAllow notifications to keep track of important info, like if your buddy has left a safe zone, or if you should consider charging your device. @@ -152,10 +131,7 @@ Select \'Pet\' > \'Tracker\'. Click \'GPS Update\' Select 3/5/10/15 minutes. (Shorter network intervals drain the Tracker\'s battery faster. By default, the network reconnects every 15 minutes.) When Live mode is activated, the Tracker enters a rapid positioning and networking state, usually within 15–20 seconds. This mode drains the battery the quickest, so it\'s best reserved for emergency situations. - 4.Turn on Notifications: Go to \'Account\' > \'Settings\'. Click \'Notifications\' and turn on - Renewal: - /month x%s - /%s year + Renewal: Will send verification code to %s. Upgrade to Prime to Unlock\nExclusive Features! New Firmware Version Detected: %s @@ -179,69 +155,16 @@ 1.1 device replacement included\n2.Dedicated customer support\n3.Annual protection coverage 1.VIP priority support\n2.Fast replacement service (1 included)\n3.Enhanced protection\n4.Hassle-free pet protection %s min - As of %s %s Min - By using our app, you agree to our Privacy Policy and Terms. We may update these occasionally - your continued use means you accept any changes. - Yes - Copyright © %d ABBIDOT All rights reserved - %d Trackers - %d Pets - %d in - Failed to get permission - No Pets - Please bind a pet first - %d%% - %dY %dMon - All videos - Complete(%1$d/%2$d) - Supports up to %d photos or videos - Supports up to %d photos - Supports up to %d videos - The width of the photo should be greater than %1$d and the height should be greater than %1$d - Please allow relevant permissions - Please allow relevant permissions - %1$d/%2$d - Today\t%s - Video selection - $\t%.2f - %s%% - Enter registered email address to your profile. We \nwill send 4 digits code to your email. - $%s - $%s/month - $%s/year - This will delete all of %s data permanently from your account. - (Renew at $%s per year) - Activation\nSuccessful - Starting %s-min Live - Code valid for %ss - Your friend %s invites you to become %s family. - Renewal: $%s/year on %s - Renewal: $%s/month on %s - Annual Care Protection - (Renew at $%s per year thereafter) - (Renew at $%s per month thereafter) - Fail - Edit Payment Method - No signal. Check if pet indoors. Card number already exists. Overwrite it? - Please enter password. - Please enter email address. Wi-Fi ensures your tracker stays connected when LTE signals are weak. Renewal: $%s/%s day on %s /day x%s - ABBIDOT APP collects location data,The route and distance between the current location and the device can be calculated. - (Renew at $%s per day thereafter) - (Renew at $%s/%s days thereafter) - (Renew at $%s/%s years thereafter) - (Renew at $%s/%s months thereafter) %s Year Care - Expiry Time: 1 replacement/year, any reason Bluetooth Radar Saved. Active when online. - Renewal: $%s/%s years on %s - Renewal: $%s/%s months on %s Refund period has expired Refund Policy\n Automatic Refund (Within 48 Hours) @@ -250,330 +173,140 @@ After the initial 48-hour period, users may request a refund within 30 days of purchase.\n\t1.All subscription plans (3-Month, 1-Year, 2-Year) are eligible\n\t2.Refund requests are subject to review and approval\n\t3.Refunds may be partially adjusted based on usage and service consumption\n Subscriptions older than 30 days are non-refundable. No Refund After 30 Days - + Garden + Park + Play + Unsafe + Vegetable Garden + Water Welcome back Email - Phone Password Forgot password? - Log in with WeChat - Log in with verification code - Log in with Apple - Log in with account - Set new password - Verification code sent Don’t have an account? - Log in with password Sign up - Hey, Return to log in - Set Log in password Full name - Get - We have sent the verification code to your email - Verification code Next Resend Continue with acceptance. - Please read and agree - and - Terms of Use - Privacy Policy Submit - Binding - Completed - Data Map Profile - My Orders - Help Center - Feedback Settings - Setting Notification - Language Account About Clear Cache - Log Out Feedback Question type (required) About APP About Tracker Others Please enter your problem or suggestion - Please select question type Please leave your email so we can help you faster Upload Image Name - Gender Birthday - Location Email - Phone - Breed Weight Height How to measure height Save Tags - Enter Tracker ID Activate - Activate the device to continue No, thanks - Activate My Tracker - Trackers - My Tracker - Authorized LED Light - Fence - Setting New Pet Unbind Network GPS - Days Bluetooth connected Bluetooth not connected - LED Light Off On - Fence - Family - Add Family - Invite you family to share the location or activity of the pet. Family members cannot create fences or modify settings. Invite Successfully sent - Back GPS Updates - Turn Off - Fences - Fence Detail Name Shape Activate Fence - Radius Finish - Current Sustained Breathing mode - Slow flash Flash My Pet - Pets - My Pets - Authorized Male Female - About Edit - Activity Badges - All - Cancel All - Low Battery Stop Live - Live will update the location in time, but it will consume more power - Select map - Google Map - Gaode Map Cancel - The APP is not installed, please download and install the app first Active Time - Goal - Distance Calories - Tracking Time - Sleep Time - Active Time - History - Activity Details Set Goal Change Current - Track - Point min - s mile kcal - days Please fill in completely - Email format is incorrect Successful Uploaded successfully - Added successfully Saved successfully Log in successful Successfully changed Tips Add Fences - Edit Fences - Forgot password No data - Successfully deleted Are you sure you want to delete? - Are you sure you want to unbind the device? - Unbinding successfully - Binding successful - Weight must be greater than 0 Today min - s - mile - kcal days - Your device has expired, please renew Stop Live Tracking? Delete Cancel - Y Mon Yes Notifications - Select all - Cancel all Request failed, please try again - Map loading… - Registered successfully - Hello blank fragment All photos - Photos and Videos - Select - Preview - Only one type of file can be selected - Failed to start the camera - Wrong picture Please allow relevant permissions - This image format is not supported Edit - Clear - No matching photos - No matching videos - Original - Finish - Cancel - Template - Text - Date - Double click to edit - Customize - Photo selection - GIF - Days Auto-Renew: - Recharge History Recharge - Recharge Amount - Order Details - Subtotal - Coupon - Promo Code - Integration Grand Total - Pay - Select Payment Method - Add New Card - Confirm - Payment - Payment Successful - Payment failed, please try again Try Again Back - Subscription Plan: - Payment Interval: - Expiration Date: - English Are you sure you want to log out? Confirm clearing app cache? Light Mode - Firmware Upgrade - Successfully submitted - Cleared successfully Loading… - Log in failed. Please try again Cancel auto-subscription? Confirm? - Auto-subscription cancelled successfully Auto-subscription is convenient as no expiry concerns Card Number - Cardholder Name - CARD HOLDER - EXPIRIATION DATE MM/YY CVV - Please select the mode of payment - User cancels payment Payment successful Payment failed, please try again - Invalid expiration date - Invalid credit card format - Are you sure you want to turn off the device? - Crop Connecting to Bluetooth - Cancel account Canceling your account will permanently delete all data. Are you sure? - Account successfully canceled - Press again to exit the app Incorrect username or password Verification code error Verification code expired - Registration failed User does not exist User already exists - Incorrect email format - Disconnect device? - Connection successful - Connection failed - Activation successful - Activation failed, please try again - Initial log in - Please connect your mobile number - Please enter your mobile phone number Reset password - Submit an order - $ - Days left for use - Validity period - Days - Device - Reactivate - Total amount - Abbidot Privacy Policy Website - Reset password - Cancel payment Turn on phone Bluetooth please You cannot share with yourself - Current user has already bound this device - First Name - Last Name Online Offline - Legal Information - I Accept - Decline - No download address - Do you want to download firmware and upgrade? - Please wait… - Version Description - Firmware Name Firmware Version - Firmware file size Upgrade - Upgrade successful - Upgrade failed - Download firmware - Entering DFU mode - Search for DUF devices Device does not exist - Connecting devices - Reconnect equipment - Device disconnected Disconnected - Upgrading - Preparing for Upgrade - Device successfully connected Already latest version Activity Route @@ -582,36 +315,27 @@ KM Sleep Live - Zone Tracker Badges View all Manage Time - Start Time - Virtual Fences WiFi Zone Connected Weak signal - Battery Bluetooth Light - From - To Check the track and points Read All Subscription Help How It Works - FAQ Units Setting - Shop Sign Out Calories Avg. Time Avg. Total Data hrs - Total Distance Last 7 days Last 30 days Ok @@ -627,21 +351,7 @@ October November December - Jan - Feb - Mar - Apr - May - Jun - Jul - Aug - Sep - Oct - Nov - Dec - Direction As sound speeds up, the distance is closer. - Speed Stop Radar Edit WiFi Zone WiFi Name: @@ -656,12 +366,9 @@ Add No-go Zone Edit No-go Zone Data Board - minimum - Recommenced hr Set Daily Goal Awesome! Ready to begin! - Total activity distance km Daily Avg. activity time Avg. Calories @@ -679,22 +386,16 @@ Members Active Pending - Relation Choose avatar - Friend - Love Unlock New Milestones! - Colleague Congratulations! Share Log in Sign up Create account - Privacy Policy. Minimum 6 characters Country Email Address - Welcome back Continue OTP verification sec @@ -703,19 +404,15 @@ Reset Now Confirm Password Password reset successful! - Reset Standard Satellite Display Fences - Enter Select Always By Your Side! Powered by View Less See All Adventure - Social - Sporty New Tracker Add new tracker Charge and Power On @@ -735,18 +432,14 @@ Monthly Subscription /month /year - Best value + Best Value Confirm Your Plan Device Number Terms and Conditions - Auto Renew - About Auto Renew - Your annual subscription will automatically renew at the end of each period for uninterrupted service. Summary Tax - Total with Tax Payment Method - My Card + My Card No Payment Method + Add New Card Primary @@ -755,19 +448,14 @@ Add Payment Method Save New Card Payment was Successful - MM/YY - CVC Accepted Payment Cards Set as primary Card Name On Card Permissions Skip - Enable Grant permissions for better experience. - Subscription Detail Tracker ID - Plan: - per year) + Plan: Renews On: Adding where they live can improve battery and provide extra safety Establish WiFi Zone @@ -775,26 +463,19 @@ Permanent Residence Choose Wi-Fi network Later - What is your pet Measurement Units? - Your pet’s height - Length - Your pet’s weight Notifications Setting Enter or leave Safe Zone/No-go Zone Tracker Status Subscription/Battery Warnings/Power Off Active/sleep reminder/goal achievement - WiFi Zone About WiFi Zone Choose a network in a trusted space where your spents lots of time. Like your home. Once in range, your tracker will recognize this network as a WiFi Zone. Office - As long as your tracker detects your buddy is safe and sound in a WiFi Zone, it will keep LIVE Tracking, Light and Sound off to extend battery life. Save Power With Bluetooth range? Pinpoint a nearby tracker using Radar. Live will also become available, but using it will end power saving. Tracking your pet WiFi Zone Settings Please enter your feedback - Please leave your email, we can help you faster Enter Your Email Address Choose File Power Off @@ -803,7 +484,6 @@ Current LED Left the safe zone In the WiFi Zone - Left the WiFi Zone In the no-go zone Strong signal WiFi Zone @@ -815,33 +495,22 @@ To ABBIDOT Entered passwords differ! No Member, yet - +Invite Invite Members - This will delete all of - data permanently from your account. Home Live Duration About Live Duration Live Mode helps find pets with location updates every 2~3 seconds, but uses more battery. You’ll still get regular updates with default tracking. Live Tracking will stop at the end of the set duration, but you can stop it before to save battery. Keep it short - Bluetooth GPS Location Receive Notifications Turn ON Device not activated. Subscribe to activate. - hours - Searching… Keep tracker on and nearby to scan. Outside Inside - 7 Days Avg. - Stop Auto Renew - Auto Renew You have created too many fences LIVE has ended. LIVE time can set through Live Duration. - Weak GPS signal - No network signal Tracker power off Starting Live… Connecting to network @@ -854,14 +523,11 @@ Live Tracking will stop in one hour, but you can stop it before to save battery. Resting Resting time - Resting Time No signal WiFi Select measurement unit - Metric(cm, kg) + Metric(cm, kg) Imperial(in, lb) - km/h - mph m ft Fences Alerts @@ -870,7 +536,6 @@ Type Message Please continue to verify your email Code valid for - minutes Create password Change Email successful! Change Email @@ -880,7 +545,7 @@ Yesterday Power On/Off Charge and unplug to turn on \nFlashing green light = on - 1.Choose a subscription \n2.Tap to activate the tracker \n3.Enable GPS and cellular tracking + 1. Choose a subscription \n2. Tap to activate the tracker \n3. Enable GPS and cellular tracking Active Tracker (The GPS and cellular network conditions can vary depending on the environment. Before placing it on your pet, check various locations around you to evaluate the GPS and network status.) Check Tracker Status @@ -943,18 +608,14 @@ Five years of commitment will unlock the Furr-timer Friend badge! How to get? Family Invitation - Activated Time: - Your friend - invites you to become - family. - Expires On: + Active Time: + Expires On: Expired on: YEARS MONTHS DAYS - Auto-renew Subscription Order - Order ID: + Order ID: Enter your reason for the refund Request a refund Refund @@ -962,13 +623,10 @@ Refunding Refunded /year on - Renewal: /month on Replacement Guarantee - Enter discount code Annual Care - Annual Care: - Bluetooth connection failed + Annual Care: LED Light Settings When the tracker is next to your phone, it is recommended to connect to the tracker via Bluetooth and adjust the LED settings. The changes will take effect immediately. Bluetooth Setup @@ -1012,7 +670,7 @@ Annual Care included, non-adjustable Delete successfully Sure to delete this card? - Account exists. Log in now? + Account exists. Log in now? Selected date is out of range Shake to turn on \nFlashing green light confirms on GPS and cellular signals may vary by location. \nTest in different locations before use. @@ -1021,25 +679,14 @@ Baidu Maps Send To turn on, connect the power cable. After first-time startup, shake to turn on. - 1 Year Subscription - 2 Year Subscription - 3 Year Subscription As low as Payment Manager - Billed annually Basic Plan Premium Plan - Real-time Tracking - Activity/Resting Logs - Notifications for Emergencies Customized LED Geofencing Route History Records - Family Members Sharing - 30-days Return Guarantee - The program has an exception and is about to exit Activate Subscription - Powered off Charging Total Time Live works on cellular only @@ -1055,8 +702,6 @@ Tone Locate works on cellular only Pet is close, try Radar - Pull to load more - Release to load Fully charged Timeline Keep phone close to device @@ -1065,37 +710,293 @@ First use Daily use Sleep Mode - 1.15 minutes no movement → sleep mode. \n2.Auto wake on movement. \n3.Battery updates every 24 hours. + 1. 15 minutes no movement → sleep mode. \n2. Auto wake on movement. \n3. Battery updates every 24 hours. WiFi Zone(Home) - 1.Connect to home WiFi. \n2.GPS off → save battery. \n3.Update every ~60 minutes. - 1.Select 3–15 min. \n2.Short interval = higher battery use. \n3.Default: 5 min. + 1. Connect to home WiFi. \n2. GPS off → save battery. \n3. Update every ~60 minutes. + 1. Select 3–15 min. \n2. Short interval = higher battery use. \n3. Default: 5 min. Set Fence type Safe Zone or No-go Zone Set boundary Enable alerts in Account > Settings > Notifications Edit or delete fence in Manage - Total Initializing Device Add Wi-Fi zone to prolong care time Add Already at minimum size - Display All Pets - Please use a valid phone number - Account - terms_en.html - privacy_en.html - subscription_terms_conditions_en.html - 该手机号码已被绑定 - + 3 Months Flex Plan + 1 Year Plus Plan + 2 Years Protection+ Plan + Billed quarterly + Billed annually + Billed every 2 years + Login with + My Card + Edit Payment Method + Your phone number has already been bound Go to Pet > Tracker Pet > Tracker > GPS Update Pet > My Pet Fence > Manage > + Add New Check: - · Network - · Bluetooth - · WiFi Zone - · Battery - · GPS - · LED + · Network\n· WiFi Zone\n· GPS + · Bluetooth\n· Battery\n· LED + Privacy Policy + Expires On + Google Map + Upgrade successful + Upgrade failed + Please enter email address. + Enter Tracker ID + No signal. Check if pet indoors. + Recommenced + Expiry Time: + Activity/Resting Logs + Real-time Tracking + Haven\’t received the email? + %d Year + %d/100 Earned + Last Time: %s + Show Track & Point + Are you sure you want to share the pet’s data with \' %s \'? + Please select 2 \~ 9 photos + Renew at %.2f per year thereafter, cancel anytime + $%doff already + The subscription plan is active until %s + Auto-renewal is off and the subscription plan will not be available after %s + Save & Confirm + $%s/month + You have successfully setup your pet and you \nearned the Safety badge! + Device already bound, please verify \nand try again + %sft + %smph + Are you sure you want to delete the family %s? + 4.Turn on Notifications: Go to \'Account\' > \'Settings\'. Click \'Notifications\' and turn on + /month x%s + /%s year + As of %s + By using our app, you agree to our Privacy Policy and Terms. We may update these occasionally - your continued use means you accept any changes. + Phone + Log in with WeChat + Log in with verification code + Log in with Apple + Log in with account + Set new password + Verification code sent + Log in with password + Hey, + Set Log in password + Get + We have sent the verification code to your email + Verification code + Please read and agree + and + Terms of Use + Binding + Completed + Data + My Orders + Help Center + Feedback + Setting + Language + Log Out + Please select question type + Gender + Location + Phone + Breed + Activate the device to continue + Activate + Trackers + My Tracker + Authorized + Fence + Setting + Days + LED Light + Fence + Family + Add Family + Invite you family to share the location or activity of the pet. Family members cannot create fences or modify settings. + Back + Turn Off + Activity Badges + Select map + Gaode Map + The APP is not installed, please download and install the app first + Added successfully + Successfully deleted + Are you sure you want to unbind the device? + Unbinding successfully + Binding successful + mile + kcal + Your device has expired, please renew + Map loading… + Hello blank fragment + Photos and Videos + Select + Preview + Only one type of file can be selected + Failed to start the camera + Wrong picture + This image format is not supported + Clear + No matching photos + No matching videos + Original + Finish + Cancel + Template + Text + Date + Double click to edit + Customize + Photo selection + GIF + Add New Card + Payment + Subscription Plan: + Firmware Upgrade + Successfully submitted + Cleared successfully + Log in failed. Please try again + Cardholder Name + CARD HOLDER + EXPIRIATION DATE + Invalid expiration date + Invalid credit card format + Are you sure you want to turn off the device? + Crop + Press again to exit the app + Registration failed + Incorrect email format + Disconnect device? + Connection successful + Connection failed + Please enter your mobile phone number + Abbidot + Reset password + Cancel payment + Current user has already bound this device + First Name + Last Name + Legal Information + I Accept + Decline + No download address + Please wait… + Version Description + Firmware Name + Firmware file size + Download firmware + Entering DFU mode + Search for DUF devices + Connecting devices + Reconnect equipment + Device disconnected + Upgrading + Preparing for Upgrade + Device successfully connected + Battery + Jan + Feb + Mar + Apr + May + Jun + Jul + Aug + Sep + Oct + Nov + Dec + minimum + Total activity distance + Welcome back + MM/YY + CVC + Enable + per year) + As long as your tracker detects your buddy is safe and sound in a WiFi Zone, it will keep LIVE Tracking, Light and Sound off to extend battery life. + +Invite + This will delete all of + data permanently from your account. + Bluetooth + Searching… + 7 Days Avg. + Weak GPS signal + No network signal + Resting Time + km/h + mph + Your friend + invites you to become + family. + Auto-renew + Renewal: + Notifications for Emergencies + Family Members Sharing + 30-days Return Guarantee + The program has an exception and is about to exit + Powered off + Pull to load more + Release to load + Total + Display All Pets + Please use a valid phone number + Account + 1. Flexible short-term protection\n\n2. 30-day money-back guarantee + 1. Dedicated customer support\n\n2. Annual protection coverage\n\n3. 30-day money-back guarantee + 1. Free device replacement included (1x)\n\n2. Enhanced protection\n\n3. Hassle-free pet protection\n\n4. 30-day money-back guarantee + Copyright © %d ABBIDOT All rights reserved + %d Trackers + %d Pets + %d in + Failed to get permission + No Pets + Please bind a pet first + %d%% + %dY %dMon + All videos + Complete(%1$d/%2$d) + Supports up to %d photos or videos + Supports up to %d photos + Supports up to %d videos + The width of the photo should be greater than %1$d and the height should be greater than %1$d + Please allow relevant permissions + Please allow relevant permissions + %1$d/%2$d + Today\t%s + Video selection + $\t%.2f + %s%% + Enter registered email address to your profile. We \nwill send 4 digits code to your email. + $%s + $%s/month + $%s/year + This will delete all of %s data permanently from your account. + (Renew at $%s per year) + Activation\nSuccessful + Starting %s-min Live + Code valid for %ss + Your friend %s invites you to become %s family. + Renewal: $%s/year on %s + Renewal: $%s/month on %s + Annual Care Protection + (Renew at $%s per year thereafter) + (Renew at $%s per month thereafter) + Fail + Edit Payment Method + Please enter password. + ABBIDOT APP collects location data,The route and distance between the current location and the device can be calculated. + (Renew at $%s per day thereafter) + (Renew at $%s/%s days thereafter) + (Renew at $%s/%s years thereafter) + (Renew at $%s/%s months thereafter) + Renewal: $%s/%s years on %s + Renewal: $%s/%s months on %s + terms_en.html + privacy_en.html + subscription_terms_conditions_en.html \ No newline at end of file diff --git a/baselibrary/src/main/java/com/abbidot/baselibrary/constant/EventName.kt b/baselibrary/src/main/java/com/abbidot/baselibrary/constant/EventName.kt index d1f60ee..d20095d 100644 --- a/baselibrary/src/main/java/com/abbidot/baselibrary/constant/EventName.kt +++ b/baselibrary/src/main/java/com/abbidot/baselibrary/constant/EventName.kt @@ -35,7 +35,7 @@ import androidx.annotation.StringDef EventName.LiveAutoEnd, EventName.LiveOpenTimeOut, EventName.SetGoal, - EventName.RefreshMessage, + EventName.LocationData, EventName.BluetoothSwitch, EventName.PostValue, EventName.BleReport, @@ -54,7 +54,7 @@ annotation class EventName { const val UpdateUserInfo = "updateUserInfo" const val UpdateData = "updateData" const val RefreshFences = "refreshFences" - const val RefreshMessage = "refreshMessage" + const val LocationData = "locationData" const val DeleteFences = "deleteFences" const val RefreshDevice = "refreshDevice" const val DeleteDevice = "deleteDevice" diff --git a/baselibrary/src/main/java/com/abbidot/baselibrary/util/AppUtils.kt b/baselibrary/src/main/java/com/abbidot/baselibrary/util/AppUtils.kt index 90d27f8..bff2f36 100644 --- a/baselibrary/src/main/java/com/abbidot/baselibrary/util/AppUtils.kt +++ b/baselibrary/src/main/java/com/abbidot/baselibrary/util/AppUtils.kt @@ -94,7 +94,7 @@ class AppUtils { * 是否是国内 */ fun isChina(type: String = SWITCH_PAGE_TYPE): Boolean { - return true + return false if (isDebug()) { if (type == SWITCH_MAP_TYPE && MMKVUtil.getBoolean(MMKVKey.OnlyGoogleMap, false)) { //只启用谷歌地图